That was actually the example I used to implement this.  As it turns out, 
assoc-in, update-in, etc. work on anything that supports assoc.

On Wednesday, 20 April 2016 13:39:40 UTC-7, Andy Fingerhut wrote:
>
> I don't know if assoc-in etc. work on the clojure.data.priority-map data 
> structures, but your questions at least reminded me of the implementation 
> of that data structure, which uses two maps internally to maintain the 
> priority map, and keeps their contents consistent with each other [1].  It 
> also implements all of the methods that regular Clojure maps do, so all 
> normal map operations work on priority-maps, too.  Its implementation may 
> give you some ideas for one way to do what you are hoping for.
>
> Andy
>
> [1] https://github.com/clojure/data.priority-map
>
>
> On Wed, Apr 20, 2016 at 10:18 AM, JvJ <kfjwh...@gmail.com <javascript:>> 
> wrote:
>
>> I had a bit of trouble fully understanding the EAV concept or the pldb 
>> code.  There's not a good overview of EAV architecture that doesn't focus 
>> on databases.  I'm not much of a DB guy.  So, I'm not sure if I got the 
>> essence of the EAV pattern with my new implementation, but here it is 
>> anyway:
>>
>> I think the legacy of object-orientation was so embedded in my brain that 
>> I failed to see the simple solution: rows and columns.  I was thinking of 
>> items in the map as "containers" of items, when I could have been thinking 
>> of them as rows in a table.  The table is effectively a sparse matrix.
>>
>> The implementation's main map is of type { [row col]->Item }.  It also 
>> uses two other maps: row-idx:{row->{col item}} and 
>> col-idx:{col->{row->item}}.
>>
>> Whenever an assoc occurs on key [r c] and item i, here is how the values 
>> are updated:
>> main-map<-(assoc main-map [r c] i)
>> row-idx<-(assoc-in row-idx [r c] i)
>> col-idx<-(assoc-in col-idx [c r] i)
>>
>> This way, we efficiently maintain row-idx and col-idx, two complementary 
>> nested maps that mirror each others' structure.
>>
>> Did I get close to the EAV pattern here?  Also, I wonder if this approach 
>> is scalable to higher-dimensional tables, for instance where each item is 
>> associated with a 3-tuple.
>>
>> On Monday, 18 April 2016 17:18:45 UTC-7, tbc++ wrote:
>>>
>>> Core.logic has one such implementation: 
>>> https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/pldb.clj
>>>  
>>> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fclojure%2Fcore.logic%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fclojure%2Fclojure%2Fcore%2Flogic%2Fpldb.clj&sa=D&sntz=1&usg=AFQjCNGjJWdatQscPmDIx3xpBMuwPmOH7A>
>>>  
>>> might be a place to start. 
>>>
>>> On Mon, Apr 18, 2016 at 5:35 PM, JvJ <kfjwh...@gmail.com> wrote:
>>>
>>>> Can you point me to a working example of one of these structures?
>>>>
>>>> On Monday, 18 April 2016 16:30:17 UTC-7, tbc++ wrote:
>>>>>
>>>>> And by "fairly common these days", I mean that I run into this sort of 
>>>>> structure a lot in clojure with anything that is trying to logic or query 
>>>>> operations. Probably isn't that common outside of projects in that 
>>>>> domain. 
>>>>>
>>>>> On Mon, Apr 18, 2016 at 5:28 PM, Timothy Baldridge <tbald...@gmail.com
>>>>> > wrote:
>>>>>
>>>>>> assoc-in is defined in terms of assoc: 
>>>>>> https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L5901
>>>>>>
>>>>>> And this structure is fairly common these days, it's basically a 
>>>>>> index of tuples [e a v], and you're creating a eav index and then an av 
>>>>>> index. Datomic does this same sort of thing, for the datom [e a v t] it 
>>>>>> creates indices for :eavt :avet and a few others that escape my memory 
>>>>>> at 
>>>>>> the moment.  
>>>>>>
>>>>>> On Mon, Apr 18, 2016 at 5:08 PM, JvJ <kfjwh...@gmail.com> wrote:
>>>>>>
>>>>>>> I'm implementing a map data structure where most of the values are 
>>>>>>> maps or sets, and these values can be cross-indexed by the keys they 
>>>>>>> contain.  I don't know if it already has a name, but I'm calling it a 
>>>>>>> cross-map.  It's similar to a two-way map, but they're not the same 
>>>>>>> thing.
>>>>>>>
>>>>>>> For instance, a common operation would be something like "give me 
>>>>>>> all values of this map that contain the key :a."
>>>>>>>
>>>>>>> In order to do this efficiently, I'm maintaining a second map that 
>>>>>>> maps keys in the values of the main map to keys of the main map whose 
>>>>>>> values contain that key.
>>>>>>>
>>>>>>> If that sounds confusing, consider this:
>>>>>>> main-map:
>>>>>>> {:foo {:a 1 :b 2} :bar {:a 2 :c 4} :baz {:b 3 :c 5}}
>>>>>>>
>>>>>>> Corresponding cross-indices:
>>>>>>> {:a #{:foo :bar} :b #{:foo :baz} :c #{:bar :baz}}
>>>>>>>
>>>>>>> As you can see, each key maintains references to those entries where 
>>>>>>> it is found.
>>>>>>>
>>>>>>> When a nested update occurs that adds an entry to one of the main 
>>>>>>> map's values, the efficient thing to do would be to simply conj that 
>>>>>>> new 
>>>>>>> key onto its corresponding cross-index set.
>>>>>>>
>>>>>>> However, I am trying to implement this as a clojure IPersistentMap, 
>>>>>>> and the only method I can override is assoc, not assoc-in.
>>>>>>>
>>>>>>> Using regular assoc, I would have to compare the old value's keys to 
>>>>>>> the new value's keys and find the set difference of the two, which is 
>>>>>>> not 
>>>>>>> an O(1) operation.
>>>>>>>
>>>>>>> Is there any way to override the behaviour of nested associations or 
>>>>>>> updates?
>>>>>>>
>>>>>>> Thanks
>>>>>>>
>>>>>>> --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Clojure" group.
>>>>>>> To post to this group, send email to clo...@googlegroups.com
>>>>>>> Note that posts from new members are moderated - please be patient 
>>>>>>> with your first post.
>>>>>>> To unsubscribe from this group, send email to
>>>>>>> clojure+u...@googlegroups.com
>>>>>>> For more options, visit this group at
>>>>>>> http://groups.google.com/group/clojure?hl=en
>>>>>>> ---
>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>> Groups "Clojure" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>> send an email to clojure+u...@googlegroups.com.
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> -- 
>>>>>> “One of the main causes of the fall of the Roman Empire was 
>>>>>> that–lacking zero–they had no way to indicate successful termination of 
>>>>>> their C programs.”
>>>>>> (Robert Firth) 
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> -- 
>>>>> “One of the main causes of the fall of the Roman Empire was 
>>>>> that–lacking zero–they had no way to indicate successful termination of 
>>>>> their C programs.”
>>>>> (Robert Firth) 
>>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with 
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clojure+u...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>>
>>> -- 
>>> “One of the main causes of the fall of the Roman Empire was that–lacking 
>>> zero–they had no way to indicate successful termination of their C 
>>> programs.”
>>> (Robert Firth) 
>>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> <javascript:>
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com <javascript:>
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to