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] ...@@ -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} err := arn.node.PActivate(ctx); if err != nil { return nil, err}
defer arn.node.PDeactivate() defer arn.node.PDeactivate()
for _, rchild := range av.Expand(arn) { children := av.Expand(arn)
if !δZTC.Has(rchild.node.POid()) { for _, rchild := range children {
coid := rchild.node.POid()
if !( δZTC.Has(coid) ||
/* embedded bucket */
(len(children) == 1 && coid == zodb.InvalidOid) ) {
continue continue
} }
...@@ -756,7 +760,10 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -756,7 +760,10 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
} }
// δ <- δA // δ <- δA
δMerge(δ, δA) err = δMerge(δ, δA)
if err != nil {
return nil, err
}
// XXX Adone <- δA // XXX Adone <- δA
// XXX Bqueue <- δA // XXX Bqueue <- δA
...@@ -765,7 +772,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -765,7 +772,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
} }
} }
for len(Aqueue) > 0 || len(Bqueue) > 0 {
// expand keys in new δA -> in B till buckets; // expand keys in new δA -> in B till buckets;
// process B buckets that cover new keys into δ+ // process B buckets that cover new keys into δ+
if b != nil { if b != nil {
...@@ -788,120 +795,25 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -788,120 +795,25 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
} }
// δ <- δB // δ <- δB
δMerge(δ, δB) err = δMerge(δ, δB)
if err != nil {
return nil, err
}
// Aqueue <- δB // Aqueue <- δB
for k, δv := range δ { for k, δv := range δ {
if !Adone.Has(k) { if !Adone.Has(k) {
Aqueue.Add(k) Aqueue.Add(k)
} }
}
_ = δv
} }
// [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
}
}
}
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
δMerge(δ, δc)
// 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
}
}
}
}
return δ, nil return δ, nil
} }
...@@ -909,7 +821,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -909,7 +821,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δMerge merges changes from δ2 into δ. // δMerge merges changes from δ2 into δ.
// δ is total-building diff, while δ2 is diff from comparing some subnodes. // δ 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 // merge δ <- δ2
for k, δv2 := range δ2 { for k, δv2 := range δ2 {
δv1, already := δ[k] δv1, already := δ[k]
...@@ -923,7 +835,7 @@ func δMerge(δ, δ2 map[Key]ΔValue) { ...@@ -923,7 +835,7 @@ func δMerge(δ, δ2 map[Key]ΔValue) {
// XXX also handle ø->ø + ø->c i.e. [k] was hole and become value // XXX also handle ø->ø + ø->c i.e. [k] was hole and become value
if !( (δv1.New == VDEL && δv2.Old == VDEL) || if !( (δv1.New == VDEL && δv2.Old == VDEL) ||
(δv1.Old == VDEL && δv2.New == VDEL) ) { (δv1.Old == VDEL && δv2.New == VDEL) ) {
return nil, fmt.Errorf("BUG or btree corrupt: [%v] has " + return fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, δv1, δv2) "duplicate entries: %v, %v", k, δv1, δv2)
} }
...@@ -943,6 +855,8 @@ func δMerge(δ, δ2 map[Key]ΔValue) { ...@@ -943,6 +855,8 @@ func δMerge(δ, δ2 map[Key]ΔValue) {
delete(δ, k) 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