zope.bforest

HomePage: UNKNOWN

Author: Gary Poster

Download: https://pypi.python.org/packages/source/z/zope.bforest/zope.bforest-1.2.tar.gz

        ===========
BForest API
===========

BForests are dictionary-like objects that use multiple BTrees for a backend and
support rotation of the composite trees.  This supports various implementations 
of timed member expirations, enabling caches and semi-persistent storage.  A
useful and simple subclass would be to promote a key-value pair to the
first (newest) bucket whenever the key is accessed, for instance.  It also is
useful with disabling the rotation capability.

Like btrees, bforests come in four flavors: Integer-Integer (IIBForest), 
Integer-Object (IOBForest), Object-Integer (OIBForest), and Object-Object
(OOBForest).  The examples here will deal with them in the abstract: we will
create classes from the imaginary and representative BForest class, and
generate keys from KeyGenerator and values from ValueGenerator.  From the 
examples you should be able to extrapolate usage of all four types.

First let's instantiate a bforest and look at an empty example.  By default,
a new bforest creates two composite btree buckets.

    >>> d = BForest()
    >>> list(d.keys())
    []
    >>> list(d.values())
    []
    >>> len(d.buckets)
    2
    >>> dummy_key = KeyGenerator()
    >>> d.get(dummy_key)
    >>> d.get(dummy_key, 42)
    42

Now we'll populate it.  We'll first create a BTree we'll use to compare.

    >>> original = BForest._treemodule.BTree()
    >>> for i in range(10):
    ...     original[KeyGenerator()] = ValueGenerator()
    ... 
    >>> d.update(original)
    >>> d == original
    True
    >>> list(d) == list(original)
    True
    >>> list(d.keys()) == list(original.keys())
    True
    >>> list(d.values()) == list(original.values())
    True
    >>> list(d.items()) == list(original.items())
    True
    >>> original_min = original.minKey()
    >>> d.popitem() == (original_min, original.pop(original_min))
    True
    >>> original_min = original.minKey()
    >>> d.pop(original_min) == original.pop(original_min)
    True
    >>> len(d) == len(original)
    True

Now let's rotate the buckets.

    >>> d.rotateBucket()

...and we'll do the exact same test as above, first.

    >>> d == original
    True
    >>> list(d) == list(original)
    True
    >>> list(d.keys()) == list(original.keys())
    True
    >>> list(d.values()) == list(original.values())
    True
    >>> list(d.items()) == list(original.items())
    True
    >>> original_min = original.minKey()
    >>> d.popitem() == (original_min, original.pop(original_min))
    True
    >>> original_min = original.minKey()
    >>> d.pop(original_min) == original.pop(original_min)
    True
    >>> len(d) == len(original)
    True

Now we'll make a new dictionary to represent changes made after the bucket
rotation.

    >>> second = BForest._treemodule.BTree()
    >>> for i in range(10):
    ...     key = KeyGenerator()
    ...     value = ValueGenerator()
    ...     second[key] = value
    ...     d[key] = value
    ... 
    >>> original.update(second)

...and we'll do the exact same test as above, first.

    >>> d == original
    True
    >>> list(d) == list(original)
    True
    >>> list(d.keys()) == list(original.keys())
    True
    >>> list(d.values()) == list(original.values())
    True
    >>> list(d.items()) == list(original.items())
    True
    >>> original_min = original.minKey()
    >>> d.popitem() == (original_min, original.pop(original_min))
    True
    >>> if original_min in second:
    ...     _ = second.pop(original_min)
    >>> original_min = original.minKey()
    >>> d.pop(original_min) == original.pop(original_min)
    True
    >>> if original_min in second:
    ...     _ = second.pop(original_min)
    >>> len(d) == len(original)
    True

The bforest offers ``itervalues``, ``iterkeys``, and ``iteritems`` that have
the same extended arguments as BTrees' ``values``, ``keys``, and ``items``.

    >>> list(d.itervalues()) == list(original.values())
    True
    >>> list(d.iteritems()) == list(original.items())
    True
    >>> list(d.iterkeys()) == list(original.keys())
    True

    >>> keys = list(original)
    >>> mid = keys[len(keys)//2