Commit ce8d70fb authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6e8d3878
...@@ -708,7 +708,6 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -708,7 +708,6 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// XXX maybe walk till a from root to get more precise initial range? // XXX maybe walk till a from root to get more precise initial range?
atop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: a} // [-∞, ∞) atop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: a} // [-∞, ∞)
av = rangeSplit{atop} av = rangeSplit{atop}
fmt.Printf("X av: %s\n", av)
aq := []*nodeInRange{atop} // stack aq := []*nodeInRange{atop} // stack
for len(aq) > 0 { for len(aq) > 0 {
l := len(aq) l := len(aq)
...@@ -861,6 +860,34 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -861,6 +860,34 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
fmt.Printf(" bv: %s\n", bv) fmt.Printf(" bv: %s\n", bv)
} }
// FIXME update trackIdx
/*
// update δc -> tracked keys
// ca = nil -> add cb to tracked
// cb = nil -> remove ca from tracked
// (their siblings must be already processed by diffX call)
if ca == nil {
trackIdx[child] = nodeTrack{parent: b.POid(), trackedKeys: SetKey{}}
}
if cb == nil {
delete(trackIdx, child) // XXX remove keys from parent?
} else {
trackedKeys := trackIdx[child].trackedKeys
for k, δv := range δc {
switch {
case δv.Old == VDEL:
trackedKeys.Add(k)
case δv.New == VDEL:
trackedKeys.Add(k)
// k v1->v2 no change in key
}
}
}
*/
// A queue // A queue
Bqueue = SetKey{} Bqueue = SetKey{}
for k := range Aqueue { for k := range Aqueue {
...@@ -977,240 +1004,6 @@ func δMerge(δ, δ2 map[Key]ΔValue) error { ...@@ -977,240 +1004,6 @@ func δMerge(δ, δ2 map[Key]ΔValue) error {
} }
/*
func __diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack) (δ map[Key]ΔValue, err error) {
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 {
err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate()
av = a.Entryv() // key↑
}
if b != nil {
err = b.PActivate(ctx); if err != nil { return nil, err }
defer b.PDeactivate()
bv = b.Entryv() // key↑
}
fmt.Printf(" av: %s\n", vtree(av))
fmt.Printf(" bv: %s\n", vtree(bv))
δ = map[Key]ΔValue{}
defer fmt.Printf(" -> δt: %v\n", δ)
// [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
aChildren := map[zodb.Oid]Node{}
for _, __ := range av {
child := __.Child()
coid := child.POid()
if δZTC.Has(coid) ||
(len(av) == 1 && coid == zodb.InvalidOid) { // embedded bucket {
aChildren[coid] = child
}
}
fmt.Printf(" aChildren: %v\n", aChildren)
// -> "might be changed" subset of tracked keys
δtqkeys := SetKey{}
for achild := range aChildren {
track, ok := trackIdx[achild]
if !ok {
panicf("node %s ∈ δZTC, but its track is ø", achild)
}
δtqkeys.Update(track.trackedKeys)
}
if a != nil && len(av) == 0 { // ø tree - fetch tracked keys from it directly
δtqkeys.Update(trackIdx[a.POid()].trackedKeys)
}
fmt.Printf(" δtqkeys: %s\n", δtqkeys)
// b -> {bChildren} : coverage ∩ "might be changed" tracked keys
bChildren := map[zodb.Oid]Node{}
for i := range bv {
lo := bv[i].Key() // [lo, hi_] _not_ hi) not to overflow at ∞
hi_ := KeyMax
if i+1 < len(bv) {
hi_ = bv[i+1].Key() - 1
}
child := bv[i].Child()
// XXX dumb
for k := range δtqkeys {
if lo <= k && k <= hi_ {
bChildren[child.POid()] = child // InvalidOid = embedded bucket
break
}
}
}
fmt.Printf(" bChildren: %v\n", bChildren)
// allChildren = aChildren ∪ bChildren
allChildren := SetOid{}
for c := range aChildren { allChildren.Add(c) }
for c := range bChildren { allChildren.Add(c) }
// go through all children that potentially can add to δ and process add/del/modify
for child := range allChildren { // XXX -> sorted? FIXME wrong to traverse by oid - need to ...?
ca := aChildren[child]
cb := bChildren[child]
δc, err := diffX(ctx, ca, cb, δZTC, trackIdx)
if err != nil {
return nil, err
}
// merge δ <- δc
for k, δv1 := range δc {
δv2, already := δ[k]
if !already {
δ[k] = δv1
continue
}
// both δ and δc has [k] - it can be that key
// entry migrated from one bucket into another.
if !( (δv2.New == VDEL && δv1.Old == VDEL) ||
(δv2.Old == VDEL && δv1.New == VDEL) ) {
return nil, fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, δv1, δv2)
}
δv := ΔValue{}
if δv1.New == VDEL {
δv.Old = δv1.Old
δv.New = δv2.New
} else {
δv.Old = δv2.Old
δv.New = δv1.New
}
fmt.Printf(" [%v] merge %s %s -> %s\n", k, δv1, δv2, δv)
if δv.Old != δv.New {
δ[k] = δv
} else {
delete(δ, k)
}
}
// update δc -> tracked keys
// ca = nil -> add cb to tracked
// cb = nil -> remove ca from tracked
// (their siblings must be already processed by diffX call)
if ca == nil {
trackIdx[child] = nodeTrack{parent: b.POid(), trackedKeys: SetKey{}}
}
if cb == nil {
delete(trackIdx, child) // XXX remove keys from parent?
} else {
trackedKeys := trackIdx[child].trackedKeys
for k, δv := range δc {
switch {
case δv.Old == VDEL:
trackedKeys.Add(k)
case δv.New == VDEL:
trackedKeys.Add(k)
// k v1->v2 no change in key
}
}
}
}
*/
/*
allChildren := SetOid{}
for _, __ := range av {
child := __.Child()
aChildren[child.POid()] = child // InvalidOid = embedded bucket
allChildren.Add(child.POid())
}
for _, __ := range bv {
child := __.Child()
bChildren[child.POid()] = child // ----//----
allChildren.Add(child.POid())
}
for child := range allChildren { // XXX -> sorted?
// add/del/modify, but child is not tracked - ignore
// XXX correct only in children from a? (b could have changed children to new objects)
if !δZTC.Has(child) {
continue
}
ca := aChildren[child]
cb := bChildren[child]
δc, err := diffX(ctx, ca, cb, δZTC)
if err != nil {
return nil, err
}
// merge δ <- δc
for k, δv1 := range δc {
δv2, already := δ[k]
if !already {
δ[k] = δv1
continue
}
// both δ and δc has [k] - it can be that key
// entry migrated from one bucket into another.
if !( (δv2.New == VDEL && δv1.Old == VDEL) ||
(δv2.Old == VDEL && δv1.New == VDEL) ) {
return nil, fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, δv1, δv2)
}
δv := ΔValue{}
if δv1.New == VDEL {
δv.Old = δv1.Old
δv.New = δv2.New
} else {
δv.Old = δv2.Old
δv.New = δv1.New
}
if δv.Old != δv.New {
δ[k] = δv
} else {
delete(δ, k)
}
}
/// *
// merge Tkdel <- δc
for k, v := range δc {
if v == VDEL {
Tkdel.Add(k)
} else {
delete(Tkdel, k)
}
}
//* /
// XXX process keys from δ outside of already tracked nodes
// XXX only deleted keys - no - delete can be from untracked
// node and on tracked it is seen as addition
}
*/
/*
return δ, nil
}
*/
// diffB computes difference in between two buckets. // diffB computes difference in between two buckets.
// see diffX for details. // see diffX for details.
func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]ΔValue, err error) { func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]ΔValue, err error) {
......
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