Commit eac5d619 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 2d71c2ed
...@@ -285,7 +285,10 @@ func (δBtail *ΔBtail) Tail() zodb.Tid { return δBtail.δZtail.Tail() } ...@@ -285,7 +285,10 @@ func (δBtail *ΔBtail) Tail() zodb.Tid { return δBtail.δZtail.Tail() }
// path[0] signifies tree root. // path[0] signifies tree root.
// All path elements must be Tree except last one which must be Bucket. // All path elements must be Tree except last one which must be Bucket.
// //
// δBtail will also track all keys corresponding to added bucket nodes. XXX // Besides key (which might point to value or hole), δBtail will also track all
// keys residing in tracked leaf nodes. In particular after request for KeyMax or
// KeyMin to be tracked, δBtail will keep on tracking changes to maximum or
// minimum keys correspondingly.
// //
// XXX objects in path must be with .PJar().At() == .head // XXX objects in path must be with .PJar().At() == .head
// XXX path -> []oid ? // XXX path -> []oid ?
......
...@@ -270,10 +270,11 @@ func (tg *AllStructsSrv) AllStructs(kv1, kv2 map[Key]string, maxdepth, maxsplit, ...@@ -270,10 +270,11 @@ func (tg *AllStructsSrv) AllStructs(kv1, kv2 map[Key]string, maxdepth, maxsplit,
} }
// RBucket represents Bucket node covering [lo, hi) key range in its Tree. // RBucket represents Bucket node covering [lo, hi_] key range in its Tree.
// NOTE it is not [lo,hi) but [lo,hi_] instead to avoid overflow at KeyMax.
type RBucket struct { type RBucket struct {
// XXX +oid, +parent (RTree) // XXX +oid, +parent (RTree)
lo, hi Key lo, hi_ Key
kv map[Key]string // bucket's k->v; values were ZBlk objects whose data is loaded instead. kv map[Key]string // bucket's k->v; values were ZBlk objects whose data is loaded instead.
} }
...@@ -284,15 +285,15 @@ type RBucketSet []*RBucket // k↑ ...@@ -284,15 +285,15 @@ type RBucketSet []*RBucket // k↑
// Get returns RBucket which covers key k. // Get returns RBucket which covers key k.
func (rbs RBucketSet) Get(k Key) *RBucket { func (rbs RBucketSet) Get(k Key) *RBucket {
i := sort.Search(len(rbs), func(i int) bool { i := sort.Search(len(rbs), func(i int) bool {
return k < rbs[i].hi return k <= rbs[i].hi_
}) })
if i == len(rbs) { if i == len(rbs) {
panicf("BUG: key %v not covered; coverage: %s", k, rbs.coverage()) panicf("BUG: key %v not covered; coverage: %s", k, rbs.coverage())
} }
rb := rbs[i] rb := rbs[i]
if !(rb.lo <= k && k < rb.hi) { if !(rb.lo <= k && k <= rb.hi_) {
panicf("BUG: get(%v) -> [%v, %v); coverage: %s", k, rb.lo, rb.hi, rbs.coverage()) panicf("BUG: get(%v) -> [%v, %v]; coverage: %s", k, rb.lo, rb.hi_, rbs.coverage())
} }
return rb return rb
...@@ -308,7 +309,7 @@ func (rbs RBucketSet) coverage() string { ...@@ -308,7 +309,7 @@ func (rbs RBucketSet) coverage() string {
if s != "" { if s != "" {
s += " " s += " "
} }
s += fmt.Sprintf("[%v, %v)", rb.lo, rb.hi) s += fmt.Sprintf("[%v, %v]", rb.lo, rb.hi_)
} }
return s return s
} }
...@@ -345,7 +346,7 @@ func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) RBucketSet { ...@@ -345,7 +346,7 @@ func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) RBucketSet {
} }
// xwalkDFS walks ztree in depth-first order emitting bvisit callback on visited bucket nodes. // xwalkDFS walks ztree in depth-first order emitting bvisit callback on visited bucket nodes.
func xwalkDFS(ctx context.Context, lo, hi Key, ztree *Tree, bvisit func(*RBucket)) { func xwalkDFS(ctx context.Context, lo, hi_ Key, ztree *Tree, bvisit func(*RBucket)) {
X := exc.Raiseif X := exc.Raiseif
err := ztree.PActivate(ctx); X(err) err := ztree.PActivate(ctx); X(err)
...@@ -358,11 +359,11 @@ func xwalkDFS(ctx context.Context, lo, hi Key, ztree *Tree, bvisit func(*RBucket ...@@ -358,11 +359,11 @@ func xwalkDFS(ctx context.Context, lo, hi Key, ztree *Tree, bvisit func(*RBucket
ev := ztree.Entryv() ev := ztree.Entryv()
for i := range ev { for i := range ev {
xlo := lo; if i > 0 { xlo = ev[i].Key() } xlo := lo; if i > 0 { xlo = ev[i].Key() }
xhi := hi; if i+1 < len(ev) { xhi = ev[i+1].Key() } xhi_ := hi_; if i+1 < len(ev) { xhi_ = ev[i+1].Key() - 1 }
tchild, ok := ev[i].Child().(*Tree) tchild, ok := ev[i].Child().(*Tree)
if ok { if ok {
xwalkDFS(ctx, xlo, xhi, tchild, bvisit) xwalkDFS(ctx, xlo, xhi_, tchild, bvisit)
continue continue
} }
...@@ -386,7 +387,7 @@ func xwalkDFS(ctx context.Context, lo, hi Key, ztree *Tree, bvisit func(*RBucket ...@@ -386,7 +387,7 @@ func xwalkDFS(ctx context.Context, lo, hi Key, ztree *Tree, bvisit func(*RBucket
} }
bvisit(&RBucket{xlo, xhi, bkv}) bvisit(&RBucket{xlo, xhi_, bkv})
} }
} }
...@@ -459,10 +460,12 @@ func xverifyΔBTail(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, a ...@@ -459,10 +460,12 @@ func xverifyΔBTail(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, a
k1 := k k1 := k
k2 := k k2 := k
/*
if k == kInf { // XXX not needed? - kill? if k == kInf { // XXX not needed? - kill?
k1 = maxk1 k1 = maxk1
k2 = maxk2 k2 = maxk2
} }
*/
q1 := []Key{k1} q1 := []Key{k1}
q2 := []Key{k2} q2 := []Key{k2}
......
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