Commit 8512b5ae authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1c577863
......@@ -739,8 +739,12 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
err := arn.node.PActivate(ctx); if err != nil { return nil, err}
defer arn.node.PDeactivate()
for _, rchild := range av.Expand(arn) {
if !δZTC.Has(rchild.node.POid()) {
children := av.Expand(arn)
for _, rchild := range children {
coid := rchild.node.POid()
if !( δZTC.Has(coid) ||
/* embedded bucket */
(len(children) == 1 && coid == zodb.InvalidOid) ) {
continue
}
......@@ -756,7 +760,10 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
}
// δ <- δA
δMerge(δ, δA)
err = δMerge(δ, δA)
if err != nil {
return nil, err
}
// XXX Adone <- δA
// XXX Bqueue <- δA
......@@ -765,143 +772,48 @@ 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}
}
for k := range Bqueue {
Bdone.Add(k)
bbucket, ok, err := bv.GetToBucket(ctx, k)
if !ok {
continue // key not covered
for len(Aqueue) > 0 || len(Bqueue) > 0 {
// 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}
}
// XXX check bucket for already "done" (i.e. taken into account)
δB, err := diffB(ctx, nil, bbucket.node.(*Bucket))
if err != nil {
return nil, err
}
// δ <- δB
δMerge(δ, δB)
// Aqueue <- δB
for k, δv := range δ {
if !Adone.Has(k) {
Aqueue.Add(k)
for k := range Bqueue {
Bdone.Add(k)
bbucket, ok, err := bv.GetToBucket(ctx, k)
if !ok {
continue // key not covered
}
}
}
// XXX check bucket for already "done" (i.e. taken into account)
// [i].Key ≤ [i].Child.*.Key < [i+1].Key i ∈ [0, len([]))
//
// [0].Key = -∞ ; always returned so
// [len(ev)].Key = +∞ ; should be assumed so
// a -> aq {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
δB, err := diffB(ctx, nil, bbucket.node.(*Bucket))
if err != nil {
return nil, err
}
}
}
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
}
// δ <- δB
err = δMerge(δ, δB)
if err != nil {
return nil, err
}
// merge δ <- δc
δMerge(δ, δc)
// Aqueue <- δB
for k, δv := range δ {
if !Adone.Has(k) {
Aqueue.Add(k)
}
// update δc -> tracked keys
_ = δv
}
// 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
}
}
}
}
}
return δ, nil
}
......@@ -909,7 +821,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δMerge merges changes from δ2 into δ.
// δ is total-building diff, while δ2 is diff from comparing some subnodes.
func δMerge(δ, δ2 map[Key]ΔValue) {
func δMerge(δ, δ2 map[Key]ΔValue) error {
// merge δ <- δ2
for k, δv2 := range δ2 {
δv1, already := δ[k]
......@@ -923,8 +835,8 @@ func δMerge(δ, δ2 map[Key]ΔValue) {
// XXX also handle ø->ø + ø->c i.e. [k] was hole and become value
if !( (δv1.New == VDEL && δv2.Old == VDEL) ||
(δv1.Old == VDEL && δv2.New == VDEL) ) {
return nil, fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, δv1, δv2)
return fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, δv1, δv2)
}
δv := ΔValue{}
......@@ -943,6 +855,8 @@ func δMerge(δ, δ2 map[Key]ΔValue) {
delete(δ, k)
}
}
return nil
}
......
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