Lets look at the upd function that is part of the map benchmark I posted
above...
(defn upd [m i]
(let [m1 (assoc m i (- i))
bb (ByteBuffer/allocate (lazy-byte-length m1))]
(lazy-write m1 bb)
(.flip bb)
(load-aamap bb)))
And its invocation...
(def lazy-m (reduce upd lazy-map (range updates)))
Here we see that upd is called repeatedly by the reduce, its first argument
being the result of the previous call to upd.
m1 (assoc m i (- i)
The above is in the upd function. It uses assoc to create an updated copy of
the map.
bb (ByteBuffer/allocate (lazy-byte-length m1)
bb is a byte buffer with a capacity equal to the length of the serialized
contents of m1.
(lazy-write m1 bb)
(.flip bb)
(load-aamap bb))
Now we write the updated map to the byte buffer, flip it, and then create a new
map from the byte buffer. This new map is then passed back to the reduce method
which calls upd again with the new/updated map.
This usage, being a benchmark, is a bit atypical as we are serializing the
contents of the map with each update and then loading the result back into a
new map. But. You can see that the map works like the standard clojure map, and
only it works additionally with the lazy-byte-length, lazy-write and aamap-load
functions. The underlying tree is not normally accessed by the application
developer, just as the red/black tree used to implement clojure sorted maps are
not normally accessed by the application developer.
So aamap is used just like sorted-map, except for the additional capability of
being able to quickly load it from and write it to a ByteBuffer. And, like a
sorted-map, you can also specify a comparator for ordering the keys, though the
comparator would be passed in the optional opts map on the aamap-load function
or in the create-lazy-aamap function.
The full API is given here:
https://github.com/laforge49/aatree/blob/master/src/aatree/core.clj (Still need
to add doc strings though.)
On Thursday, October 1, 2015 at 6:15:06 PM UTC-4, Nathan Davis wrote:
>
> Thanks, that really helps clarify things. So is the new tree saved when
> it is created (i.e., when the old tree is "updated"), or do you have to
> "write it back" at some point? In other words, as a user of aatree, do I
> obtain a new tree and then tell aatree "Here is a new tree. Please
> (incrementally) save it." Or does the mere fact that I have a new tree
> mean that it has already been saved?
>
> As for terminology, I wouldn't worry too much about using the word
> "update" when talking about immutable datastructures. Most functional
> programmers understand the term "update" to mean "make a 'copy' of
> something, with some part of it changed in some way" in such contexts. I
> think what was confusing is that (a) the Readme didn't explicitly say
> aatrees were immutable (from a value perspective) and (b) there aren't any
> examples on using the library. I think adding a few examples (with perhaps
> a little explanation of what is happening under the covers) would go a long
> way.
>
> Nathan Davis
>
> On Thursday, October 1, 2015 at 4:22:48 PM UTC-5, William la Forge wrote:
>>
>> Sorry for my bad language. I've not written much about immutable
>> structures before so old phraseology keeps coming in inappropriately.
>>
>> The structures are immutable. A change results in a new tree with only
>> the nodes which are changed (and their parent nodes) replaced. But the key
>> property here is that deserialization and serialization operations which
>> are performed on these trees are done in place, without making any new
>> nodes--thanks to the magic of atoms. So for example, if several threads are
>> accessing the same tree instance, they all share the deserialized values
>> while any changes to the tree contents results in new tree instances. I.E.
>> It is done right, to the best of my ability. (Extra eyeballs on the code
>> always being appreciated, of course!)
>>
>> Now I'm sorry for having been so terse and ambiguous. I need practice
>> talking about this stuff. So your questions are appreciated twice over! :-)
>>
>>
>> On Thursday, October 1, 2015 at 4:41:33 PM UTC-4, Nathan Davis wrote:
>>>
>>>
>>>
>>> On Thursday, October 1, 2015 at 2:58:15 PM UTC-5, William la Forge wrote:
>>>>
>>>> A value can have more than one form or implementation. For example, a
>>>> String and a char array may both represent the same value. Most objects,
>>>> for example, can be serialized. Changing the form of a value then is not a
>>>> change of value. This is the idea behind lazy deserialization /
>>>> reserialization.
>>>>
>>>>
>>>> We can represent a data structure as a tree, where the values in the
>>>> tree can be either the immutable value of the object or a read-only
>>>> ByteBuffer holding the serialized form of the value, or both. Both forms
>>>> can be held by nodes using atoms, so the form of the values can be changed
>>>> without having to create a new tree. The value remains unchanged and the
>>>> tree can be safely shared between threads.
>>>>
>>>
>>> I think we are on the same page to this point.
>>>
>>>
>>>> Lazy deserialization comes after loading a map or vector from a
>>>> ByteBuffer. Initially only the root exists, which holds only the
>>>> ByteBuffer. As you access and alter the contents of the map or vector, the
>>>> portions of the tree which are accessed are deserialized.
>>>>
>>>
>>> This is where I get confused. Are aatrees persistent structures (in the
>>> functional programming sense, like Clojure's data structures) whose values
>>> cannot be changed (although their internal representation ("form") may
>>> change), or are they mutable? If they are persistent, what do you mean by
>>> "alter the contents"?
>>>
>>> Nathan Davis
>>>
>>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.