Commit 115a4866 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1dcd1f61
......@@ -510,18 +510,27 @@ type nodeInRange struct {
type rangeSplit []*nodeInRange // key↑
// Get returns node covering key k.
// Get panics if k is outside covered range.
func (rs rangeSplit) Get(k Key) *nodeInRange { // XXX -> Get_ -> rn, ok
// Get panics if k is not covered.
func (rs rangeSplit) Get(k Key) *nodeInRange {
rnode, ok := rs.Get_(k)
if ok {
return rnode
}
panicf("key %v not covered", k)
}
// Get_ returns node covering key k.
func (rs rangeSplit) Get_(k Key) (rnode *nodeInRange, ok bool) {
i := sort.Search(len(rs), func(i int) bool {
return k <= rs[i].hi_
})
if i == len(rs) {
panicf("key %v not covered", k) // XXX + coverage: ...
return nil, false // key not covered
}
rn := rs[i]
rn = rs[i]
if !(rn.lo <= k && k <= rn.hi_) {
panicf("BUG: get(%v) -> [%v, %v]", k, rn.lo, rn.hi_)
panicf("BUG: get(%v) -> %s", k, rn)
}
return rn
......@@ -532,7 +541,9 @@ func (rs rangeSplit) Get(k Key) *nodeInRange { // XXX -> Get_ -> rn, ok
// rnode must be initially in *prs.
// rnode.node must be tree.
// rnode.node must be aleady activated.
func (prs *rangeSplit) Expand(rnode *nodeInRange) []*nodeInRange {
//
// inserted children is also return for convenience.
func (prs *rangeSplit) Expand(rnode *nodeInRange) (children rangeSplit) {
rs := *prs
i := sort.Search(len(rs), func(i int) bool {
return rnode.hi_ <= rs[i].hi_
......@@ -547,7 +558,7 @@ func (prs *rangeSplit) Expand(rnode *nodeInRange) []*nodeInRange {
// [len(ev)].Key = +∞ ; should be assumed so
tree := rnode.node.(*Tree)
treev := tree.Entryv()
children := make([]*nodeInRange, 0, len(treev)+1)
children := make(rangeSplit, 0, len(treev)+1)
for i := range treev {
lo := rnode.lo
if i > 0 {
......@@ -701,9 +712,10 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
var av rangeSplit
var bv rangeSplit
// initial phase: expand changed nodes in a till buckets
// XXX maybe walk till a from root to get more precise initial range?
// initial phase: expand changed nodes in a till buckets;
// XXX changed buckets -> δ-
if a != nil {
// XXX maybe walk till a from root to get more precise initial range?
atop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: a} // [-∞, ∞)
av = rangeSplit{atop}
aq := []*nodeInRange{atop} // stack
......@@ -712,16 +724,15 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
arn := aq[l-1]; aq=aq[:l-1] // arn=aq.pop()
err := arn.node.PActivate(ctx); if err != nil { return nil, err}
defer arn.node.PDeactivate()
children := av.Expand(arn)
for _, rc := range children {
if !δZTC.Has(rc.node.POid()) {
for _, rchild := range av.Expand(arn) {
if !δZTC.Has(rchild.node.POid()) {
continue
}
switch rc.node.(type) {
switch rchild.node.(type) {
case *Tree:
aq = append(aq, rc)
aq = append(aq, rchild)
case *Bucket:
// XXX δ += -[k]v -[k]ø (for tracked DEL)
......@@ -731,6 +742,38 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
}
// expand keys in new δA -> in B till buckets;
// process B buckets that cover new keys into δ+
if b != nil {
// XXX precise range as for a ^^^ ?
btop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: b} // [-∞, ∞)
bv = rangeSplit{btop}
}
bq := []*nodeInRange{...}
for k := range Bkeysq {
bnode, ok := bv.Get_(k)
if !ok {
continue // key not covered
}
for {
switch bnode.node.(type) {
case *Tree:
err := bnode.node.PActivate(ctx); X(err)
defer bnode.node.PDeactivate()
case *Bucket:
btree, ok := bnode.node.(*Tree
}
}
// [i].Key ≤ [i].Child.*.Key < [i+1].Key i ∈ [0, len([]))
//
......
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