Commit c0b25b92 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent a4c30ee6
...@@ -18,9 +18,60 @@ ...@@ -18,9 +18,60 @@
// See https://www.nexedi.com/licensing for rationale and options. // See https://www.nexedi.com/licensing for rationale and options.
package xbtree package xbtree
// ΔBtail
// XXX ΔBtail organization // ΔBtail provides BTree-level history tail.
//
// It translates ZODB object-level changes to information about which keys of
// which BTree were modified, and provides service to query that information.
// See ΔBtail class documentation for usage details.
//
//
// ΔBtail organization
//
// ΔBtail keeps raw ZODB history in ΔZtail and uses BTree-diff algorithm(*) to
// turn δZ into BTree-level diff. For each tracked BTree a separate ΔTtail is
// maintained with tree-level history in ΔTtail.vδT .
//
// Because it is very computationally expensive(+) to find out for an object to
// which BTree it belongs, ΔBtail cannot provide full BTree-level history given
// just ΔZtail with δZ changes. Because of this ΔBtail requires help from
// users, which are expected to call ΔBtail.Track(treepath) to let ΔBtail know
// that such and such ZODB objects constitute a path from root of a tree to some
// of its leaf. After Track call the objects from the path and tree keys, that
// were covered by leaf node, become tracked: from now-on ΔBtail will detect
// and provide BTree-level changes caused by any change of tracked tree objects
// or tracked keys. This guarantee can be provided because ΔBtail now knows
// that such and such objects belong to a particular tree.
//
// To manage knowledge which tree part is tracked ΔBtail uses PPTreeSubSet.
// This data-structure represents so-called PP-connected set of tree nodes:
// simply speaking it builds on some leafs and then includes parent(leaf),
// parent(parent(leaf)), etc. In other words it's a "parent"-closure of the
// leafs. The property of being PP-connected means that starting from any node
// from such set, it is always possible to reach root node by traversing
// .parent links, and that every intermediate node went-through during
// traversal also belongs to the set.
//
// A new Track request potentially grows tracked keys coverage. Due to this,
// ΔBtail needs to recompute potentially whole vδT of the affected tree. This
// recomputation is managed by rebuild* family of functions and uses the same
// treediff algorithm, that Update is using, but modulo PPTreeSubSet
// corresponding to δ key coverage. Update also potentially needs to rebuild
// whole vδT history, not only append new δT, because a change to tracked tree
// nodes can result in growth of tracked key coverage.
//
// Queries are relatively straightforward code that work on vδT snapshot. The
// main complexity, besides BTree-diff algorithm, lies in recomputing vδT when
// set of tracked keys changes. XXX and in concurrency
//
//
// XXX concurrency
//
//
// --------
//
// (*) implemented in treediff.go
// (+) full database scan
import ( import (
"context" "context"
...@@ -875,7 +926,7 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl ...@@ -875,7 +926,7 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl
// NOTE: no need to duplicate returned vδT slice because // NOTE: no need to duplicate returned vδT slice because
// _ΔTtail.rebuild clones vδT before modifying it. This way the data we // _ΔTtail.rebuild clones vδT before modifying it. This way the data we
// return to caller will stay unchanged even if rebuild is running // return to caller will stay unchanged even if rebuild is running
// simulataneously. // simultaneously.
return vδT[i:j+1] return vδT[i:j+1]
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment