úÎ\,X–*      !"#$%&'() Jeremy GrovenBSD3NoneA sum type to contain either a  or a  *A wrapper for keys; this has an ephemeral t that will be either  or  depending on the result of byte k.Used to indicate that a  is not terminalUsed to indicate that a  is terminal)Do the magic of wrapping up a key into a +Extract the original key from a wrapped one*#Calculate a single-byte hash for a + ,*-  ,*- Jeremy GrovenBSD3 Safe-Inferred AAlias that indicates the total number of values underneath a tree FAlias to indicate how deep a branch in a tree is. Bottoms have depth 0     Jeremy GrovenBSD3None!"T A  § is a user-visible part of a tree, i.e. a single node in the tree that can actually be manipulated by a user. This is useful when doing the work of persisting trees. ./       ./ Jeremy GrovenBSD3None!"T MThe actual Rose Tree structure. StableTree is built on one main idea: every  is either  or  . A complete Ä is one whose final element's Key is terminal, and the rest of the Keys are not (exept for two freebies at the beginning to guarantee convergence). A complete tree always has complete children.If we don't have enough data to generate a complete tree (i.e. we ran out of elements before hitting a terminal key), then an ¾ tree is generated. Incomplete trees are always contained by other incomplete trees, and a tree built from only the complete chlidren of an incomplete tree would never itself be complete.æIt is easiest to understand how this structure promotes stability by looking at how trees typically work. The easiest tree to understand is a simple, well balanced, binary tree. In that case, we would have a structure like this: ( |D| |B| |F| |A| |C| |E| |G| 7Now, suppose that we want to delete the data stored in |A|W. Then, we'll get a new structure that shares nothing in common with the original one: $ |E| |C| |G| |B| |D| |F| ÿ‘The entire tree had to be re-written. This structure is clearly unstable under mutation. Making the tree wider doesn't help much if the tree's size is changing. Simple updates to existing keys are handled well by branches with many children, but deleting from or adding to the beginning of the tree will always cause every single branch to change, which is what this structure is trying to avoid.ÿoInstead, the stable tree branches have variable child counts. A branch is considered full when its highest key is "terminal", which is determined by hashing the key and looking at some bits of the hash. I've found that a target branch size of 16 children works fairly well, so we check to see if the hash has its least-significant four bits set; if that's the case, the key is terminal. A branch gets two free children (meaning it doesn't care about whether the keys are temrinal or not), and then a run of nonterminal keys, and a final, terminal key. Under this scheme, inserting a new entry into a branch will probably mean inserting a nonterminal key, and it will probably be inserted into the run of nonterminal children. If that's the case, no neighbors will be affected, and only the parents will have to change to point to the new branch. Stability is acheived!Used to indicate that a  is completeUsed to indicate that a  is not complete StableTree0 is the user-visible type that wraps the actual @ implementation. All the public functions operate on this type.!Wrap up some of a k/v map into a . A 0k result gives a complete tree and the map updated to not have the key/values that went into that tree. A 1X result gives an incomplete tree that contains everything that the given map contained.&Generate a parent for a k/Tree map. A 0j result gives a complete tree and the map updated to not have the key/trees that went into that tree. A 1X result gives an incomplete tree that contains everything that the given map contained.XGet the key of the first entry in this branch. If the branch is empty, returns Nothing.OGet the key of the fist entry in this complete branch. This function is total.&Convert an entire Tree into a k/v map.Get the ObjectID of a tree node=Get the number of levels of branches that live below this one;Get the number of actual values that live below this branchoNon-recursive function to simply get the immediate children of the given branch. This will either give the key!value map of a Bottom, or the key!tree map of a non-bottom branch."23456789:;<=>?@ABCD87654329:;<=>?@ABCD Jeremy GrovenBSD3None ! ! ! ! Jeremy GrovenBSD3NoneT"pThings go wrong with end-user storage, but things can also go wrong with reconstructing tree values. Implement # to allow & and $ to report their own errors.$ÿÿRecord the tree into storage. This works like a fold, where the function takes an accumulating state and each tree fragment to store, while returning either an error message (which will abort the loop immediately) or the next state for the accumulator.+Any fragment referring to other fragments (Ð fragments) will be given to the fold only after all their children have been given to the fold. Exact ordering beyond that is not guaranteed, but the current behaviour is post-order depth-first traversal."#$%&'"#$%&'"#&'$%"#$%&' Jeremy GrovenBSD3None( Convert a E into a .) Convert a  back into a E() "#$%&'()()"#&'$%   ()F      !"#$%&'()*+,-./012345 6789:;9:<=>?@ABCDEFGHIJKLMNOPQRSstable-tree-0.5.0Data.StableTree.KeyData.StableTree.TypesData.StableTree.FragmentData.StableTree.TreeData.StableTree.ConversionData.StableTree.PersistData.StableTreeSomeKey SomeKey_N SomeKey_TKeyfromKey NonterminalTerminalwrapunwrap ValueCountDepthFragmentFragmentBottom fragmentMapFragmentBranch fragmentDepthfragmentChildrenTreeComplete Incomplete StableTree StableTree_C StableTree_I nextBottom nextBranchgetKey completeKey treeContents getObjectIDgetDepth getValueCountbranchContents toFragments fromFragmentsErrorstableTreeErrorstorestore'loadload'fromMaptoMapbytecereal-0.4.1.0Data.Serialize Serializefnv1afragPut$fSerializeFragmentbase Data.EitherRightLeftIBranch2IBranch1IBranch0IBottom1IBottom0BranchBottom branchShowbottomObjectIDbranchObjectIDiBottom0ObjectIDiBottom1ObjectIDiBranch0ObjectIDiBranch1ObjectIDiBranch2ObjectIDwitness$fShowStableTree $fShowTree$fEqTreecontainers-0.5.5.1 Data.Map.BaseMap