Package: lbst
lbst - Immutable Log-Balanced Search Treeprototype:With CPython, in so far, it is faster to use LBST with
1000+ items. wall-clock time benchmarks show that this datastructure
becomes interesting with PyPy 3.7 with 100+ items.BenchmarksHigher is better, less than one means copying is faster.Small number of items = 20cpython: ▇▇▇▇▇▇▇ 0.039
pypy   : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 0.262Large number of items = 1000cpython: ▇▇ 0.9489
pypy   : ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 20.15Kesako a Log-Balanced Search Tree?A search tree is a dictionary that preserves ordering according to
an user specified function, also known under the name sorted
dictionary.In the original description of the algorithm, LBST used a logarithm
function to decide how to balance the tree.Kesako an immutable datastructure?Immutable datastructures, also known under the namepersistent
datastructuresare datastructures that will produce new values
instead of changing, mutating, the value in-place.Immutable datastructures are useful in situations where you need to
keep around previous versions of the data to have an history to ease
debugging or to implement anundofeature such as in editors;
another way immutable datastructures can be put to good use is to keep
the data consistent in a concurrent or parallel programming setting,
while a flow of executition, the writer, produce a new version of the
datastructure, the readers still have access the previous version of
the truth without requiring readers to wait for the writer to finish
achieving single-writer / multiple readers without locks.When is an immutable datastructure useful?Anytime you copy abigdata structure, you may instead use an
immutable datastructure.What is the difference withdictinsertion order?Python builtindictare sorted according to the time of insertion,
if"z"is added to a dictionary first, then"a"is added, then the
dictionary will have the keys in the following order["z", ..., "a"]. That is not always the best approach performance-wise.The following kind of code is a hint that you may use LBST:frob=dict()frob[key1]=value1frob[key2]=value2frob[key3]=value3...# then re-create the dictionary with an order given by `mykeyfunc`:frob={k:vforkinsorted(frob.keys(),key=mykeyfunc)That is somekind of copy, see the previous hint, that re-orders the
dictionary keys according tomykeyfuncin order for instance to
speed up linear lookup. Using LBST, you can build alargedictionary that is sorted at construction time, save a few cycles by
avoding a reconstruction, duplicated effort, copies, and keep the
overall wall-clock time under control.lbst.make()Return an immutable search tree, ordered according to Python builtin
rich comparison, that can be overriden in user created types with the
method called__lt__.lbst.set(tree, key, value)Return a tree based ontreewherekeyis associated withvalue.lbst.get(tree, key, default=None)Return the value associated withkeyintree. Ifkeyis not
present intree, returnsdefault.lbst.delete(tree, key)Return a tree based ontreewherekeyis not present.lbst.size(tree)Return the size oftree.lbst.start(tree)Return the smallest key present intree.lbst.end(tree)Return the biggest key present intree.lbst.cursor(tree)Return a cursor fortree. The initial position is not specified. A
cursor is stateful: its position is changed / mutated in-place.lbst.cursor_clone(cursor)Return a cursor at the same position ascursorthat does not share
state withcursor.lbst.cursor_seek(cursor, key)Positioncursornearkey. Ifkeyis present in the tree
associated withcursor, then the cursor will be exactly positioned
onkeyandlbst.cursor_seekwill return0. Otherwise, whenkeyis not present in the tree associated withcursor, there is two
cases: 1) if the cursor is positioned after, thenlbst.cursor_seekreturns1, and 2) if the cursor is positioned before, thenlbst.cursor_seekreturn-1.In other words,lbst.cursor_seek:Return-1, thencursoris beforekey;Return0, thencursorisonkey;Return1, thencursoris afterkey.lbst.cursor_key(cursor)Return the key associated withcursor.lbst.cursor_value(cursor)Return the value associated withcursor.lbst.cursor_next(cursor)Movecursorto the next position, that is a bigger key that is just
after the current key. ReturnsFalseifcursorreached the end of
the key spacei.e.there is no next key. Otherwise, it returnsTrue.lbst.cursor_previous(cursor)Movecursorto the previous position, that is a smaller key that is
just before the current key. ReturnsFalseifcursorreached the start of
the key spacei.e.there is no previous key. Otherwise, it returnsTrue.lbst.to_dict(tree)Return adictrepresentation oftree. The returneddicthas the
keys in the same order astree.