Commit 45383e25 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f7a26f7d
...@@ -686,6 +686,9 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -686,6 +686,9 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
tracef(" diffT %s %s\n", xidOf(a), xidOf(b)) tracef(" diffT %s %s\n", xidOf(a), xidOf(b))
defer xerr.Contextf(&err, "diffT %s %s", xidOf(a), xidOf(b)) defer xerr.Contextf(&err, "diffT %s %s", xidOf(a), xidOf(b))
if a == nil { panic("a is nil") }
if b == nil { panic("b is nil") }
δ = map[Key]ΔValue{} δ = map[Key]ΔValue{}
defer tracef(" -> δ: %v\n", δ) defer tracef(" -> δ: %v\n", δ)
...@@ -696,37 +699,79 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -696,37 +699,79 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
Adone := SetKey{} // "processed" keys on A Adone := SetKey{} // "processed" keys on A
Bdone := SetKey{} // "processed" keys on B Bdone := SetKey{} // "processed" keys on B
if b != nil { // XXX kill (always !nil) ? // XXX precise range as for a ^^^ ?
// XXX precise range as for a ^^^ ? btop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: b} // [-∞, ∞)
btop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: b} // [-∞, ∞) bv = rangeSplit{btop}
bv = rangeSplit{btop}
}
// initial phase: expand changed nodes in a till buckets; // initial phase: expand changed nodes in a till buckets;
// XXX changed buckets -> δ- // XXX changed buckets -> δ-
if a != nil { // XXX kill (always !nil) ? // 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} aq := []*nodeInRange{atop} // stack
aq := []*nodeInRange{atop} // stack for len(aq) > 0 {
for len(aq) > 0 { l := len(aq)
l := len(aq) arn := aq[l-1]; aq=aq[:l-1] // arn=aq.pop()
arn := aq[l-1]; aq=aq[:l-1] // arn=aq.pop() atree := arn.node.(*Tree) // ok - only trees in aq
atree := arn.node.(*Tree) // ok - only trees in aq err = atree.PActivate(ctx); if err != nil { return nil, err}
err = atree.PActivate(ctx); if err != nil { return nil, err} defer atree.PDeactivate()
defer atree.PDeactivate()
// empty tree - do not expand into bucket - only process tracked holes
if len(atree.Entryv()) == 0 {
// XXX dup wrt bucket processing?
δA := map[Key]ΔValue{}
track, ok := trackIdx[atree.POid()]
if !ok {
panicf("%s ∈ δZTC, but ∉ trackIdx", vnode(atree))
}
for k := range track.holes {
δA[k] = ΔValue{VDEL, VDEL} // ø->ø indicates hole
}
// δ <- δA
err = δMerge(δ, δA)
if err != nil {
return nil, err
}
// empty tree - do not expand into bucket - only process tracked holes // Adone <- δA
if len(atree.Entryv()) == 0 { // Bqueue <- δA
// XXX dup wrt bucket processing? for k := range δA {
δA := map[Key]ΔValue{} Adone.Add(k)
track, ok := trackIdx[atree.POid()] Bqueue.Add(k)
}
arn.done = true
continue
}
// normal tree - expand till buckets
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
}
switch node := rchild.node.(type) {
case *Tree:
aq = append(aq, rchild)
case *Bucket:
δA, err := diffB(ctx, node, nil)
if err != nil {
return nil, err
}
// also -[k]ø (for tracked holes)
track, ok := trackIdx[node.POid()]
if !ok { if !ok {
panicf("%s ∈ δZTC, but ∉ trackIdx", vnode(atree)) panicf("%s ∈ δZTC, but ∉ trackIdx", vnode(node))
} }
for k := range track.holes { for k := range track.holes {
δA[k] = ΔValue{VDEL, VDEL} // ø->ø indicates hole δA[k] = ΔValue{VDEL, VDEL} // ø->ø indicates hole
} }
// δ <- δA // δ <- δA
err = δMerge(δ, δA) err = δMerge(δ, δA)
if err != nil { if err != nil {
...@@ -740,53 +785,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -740,53 +785,7 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
Bqueue.Add(k) Bqueue.Add(k)
} }
arn.done = true rchild.done = true
continue
}
// normal tree - expand till buckets
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
}
switch node := rchild.node.(type) {
case *Tree:
aq = append(aq, rchild)
case *Bucket:
δA, err := diffB(ctx, node, nil)
if err != nil {
return nil, err
}
// also -[k]ø (for tracked holes)
track, ok := trackIdx[node.POid()]
if !ok {
panicf("%s ∈ δZTC, but ∉ trackIdx", vnode(node))
}
for k := range track.holes {
δA[k] = ΔValue{VDEL, VDEL} // ø->ø indicates hole
}
// δ <- δA
err = δMerge(δ, δA)
if err != nil {
return nil, err
}
// Adone <- δA
// Bqueue <- δA
for k := range δA {
Adone.Add(k)
Bqueue.Add(k)
}
rchild.done = true
}
} }
} }
} }
......
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