Commit e75cad4a authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 07966f0d
......@@ -94,7 +94,7 @@ type BucketEntry = btree.LOBucketEntry
type Key = int64
const KeyMax Key = math.MaxInt64
//const KeyMin Key = math.MinInt64
const KeyMin Key = math.MinInt64
type Value = zodb.Oid // assumes key points to IPersistent
// deletion is represented as VDEL
const VDEL = zodb.InvalidOid
......@@ -512,7 +512,7 @@ type rangeCover []*nodeInRange // key↑
// Get returns node covering key k.
// Get panics if k is outside covered range.
func (rc rangeCover) Get(k Key) *nodeInRange {
func (rc rangeCover) Get(k Key) *nodeInRange { // XXX -> Get_ -> rn, ok
i := sort.Search(len(rc), func(i int) bool {
return k <= rc[i].hi_
})
......@@ -528,6 +528,44 @@ func (rc rangeCover) Get(k Key) *nodeInRange {
return rn
}
// Expand replaces rnode with its children.
//
// rnode must be initially in rc.
// rnode.node must be tree.
// rnode.node must be aleady activated.
func (prc *rangeCover) Expand(rnode *nodeInRange) []*nodeInRange {
rc := *prc
i := sort.Search(len(rc), func(i int) bool {
return rnode.hi_ <= rc[i].hi_
})
if i == len(rc) || rc[i] != rnode {
panicf("%s not in rangeCover", rnode)
}
// [i].Key ≤ [i].Child.*.Key < [i+1].Key i ∈ [0, len([]))
//
// [0].Key = -∞ ; always returned so
// [len(ev)].Key = +∞ ; should be assumed so
tree := rnode.node.(*Tree)
treev := tree.Entryv()
children := make([]*nodeInRange, 0, len(treev)+1)
for i := range treev {
lo := rnode.lo
if i > 0 {
lo = treev[i].Key()
}
hi_ := rnode.hi_
if i < len(treev)-1 {
hi_ = treev[i+1].Key()-1 // NOTE -1
}
children = append(children, &nodeInRange{lo, hi_, treev[i].Child()})
}
*prc = append(rc[:i], append(children, rc[i+1:]...)...)
return children
}
func (rc rangeCover) String() string {
s := ""
for _, rn := range rc {
......@@ -640,6 +678,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
fmt.Printf(" T %s %s\n", xidOf(a), xidOf(b))
defer xerr.Contextf(&err, "diffT %s %s", xidOf(a), xidOf(b))
/*
var av []TreeEntry
var bv []TreeEntry
if a != nil {
......@@ -654,16 +693,49 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
}
fmt.Printf(" av: %s\n", vtree(av))
fmt.Printf(" bv: %v\n", vtree(bv))
*/
δ = map[Key]ΔValue{}
defer fmt.Printf(" -> δt: %v\n", δ)
var av rangeCover
var bv rangeCover
// initial phase: expand changed nodes in a till buckets
// XXX maybe walk till a from root to get more precise initial range?
if a != nil {
atop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: a} // [-∞, ∞)
av = rangeCover{atop}
aq := []*nodeInRange{atop} // stack
for len(aq) > 0 {
l := len(aq)
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 {
switch rc.node.(type) {
case *Tree:
if δZTC.Has(rc.node.POid()) {
aq = append(aq, rc)
}
case *Bucket:
// XXX δ += -[k]v -[k]ø (for tracked DEL)
}
}
}
}
// [i].Key ≤ [i].Child.*.Key < [i+1].Key i ∈ [0, len([]))
//
// [0].Key = -∞ ; always returned so
// [len(ev)].Key = +∞ ; should be assumed so
// a -> {aChildren} : ∈ δZTC
// a -> aq {aChildren} : ∈ δZTC
aChildren := map[zodb.Oid]Node{}
for _, __ := range av {
child := __.Child()
......@@ -1259,6 +1331,9 @@ func vnode(node Node) string {
return fmt.Sprintf("%s%s", kind, node.POid())
}
func (rn nodeInRange) String() string {
return fmt.Sprintf("[%v,%v]%s", rn.lo, rn.hi_, vnode(rn.node))
}
func (track nodeTrack) String() string {
return fmt.Sprintf("{p%s k%s}", track.parent, track.trackedKeys)
......
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