Commit cad70d73 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 3f19a3b4
......@@ -721,6 +721,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx map[zodb.Oid]n
// δZTC is connected set of objects covering δZT (objects changed in this tree in old..new).
//
// XXX trackIdx -> just pass δBtail?
// XXX ----//---- holeIdx
func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack, holeIdx treeSetKey) (δ map[Key]ΔValue, err error) {
tracef(" diffT %s %s\n", xidOf(A), xidOf(B))
defer xerr.Contextf(&err, "diffT %s %s", xidOf(A), xidOf(B))
......@@ -795,7 +796,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
ra.done = true
case *Tree:
// empty tree - queue holes covered by it
// empty tree - only queue holes covered by it
if len(a.Entryv()) == 0 {
for k := range holeIdx.GetInRange(ra.lo, ra.hi_) {
Bktodo(k)
......@@ -803,12 +804,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
continue
}
// XXX tree with embedded bucket
// a is normal tree - expand it and queue children
// a is !empty tree - expand it and queue children
// check for each children whether it can be skipped
// XXX if a is ø tree
achildren := Av.Expand(ra)
for _, ac := range achildren {
acOid := ac.node.POid()
......@@ -854,7 +851,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
}
if found {
// ac can be skipped
// XXX Bkqueue <- holes(ac.range \ bc.range)
// XXX Bkqueue <- holes(ac.range \ bc.range) XXX test for this
continue
}
}
......@@ -915,7 +912,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
b.done = true
}
// XXX k is not there -> hole
// XXX k is not there -> hole XXX test
}
Bkqueue = SetKey{}
......@@ -956,342 +953,6 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
func __qqq__diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack) (δ map[Key]ΔValue, err error) {
// initial phase: expand changed nodes in a till buckets;
// XXX changed buckets -> δ-
var atop *nodeInRange = nil // XXX stub
av := rangeSplit{nil} // XXX stub
bv := rangeSplit{nil} // XXX stub
Aqueue := []*nodeInRange{atop} // stack: "to process" nodes on A
Bqueue := []*nodeInRange{} // stack: "to process" nodes on B
/*
for len(aq) > 0 {
l := len(aq)
arn := aq[l-1]; aq=aq[:l-1] // arn=aq.pop()
atree := arn.node.(*Tree) // ok - only trees in aq
err = atree.PActivate(ctx); if err != nil { return nil, err}
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
}
// Adone <- δA
// Bqueue <- δA
for k := range δA {
Adone.Add(k)
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 {
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
}
}
}
*/
tracef(" av: %s\n", av)
tracef(" bv: %s\n", bv)
// XXX phase 2: iterate through keys queued for A and B, delve into
// corresponding nodes, and merge diff generated from them into δ.
// Each delve for A or B, potentially adds new keys to process on the
// other side.
for {
tracef("\n")
tracef(" aq: %s\n", Aqueue)
tracef(" bq: %s\n", Bqueue)
if len(Aqueue) == 0 && len(Bqueue) == 0 {
break
}
// A queue
// Bqueue = SetKey{}
for len(Aqueue) > 0 {
anode := pop(&Aqueue)
tracef(" A %v\n", anode)
// anode is a node from A.
// it can potentially contribute to -δA if
// - Xa ∈ Tracked ∈ δZTC
// - Xa ∈ Tracked _and_ is no longer referenced
interesting := false
if δZTC.Has(anode.node.POid()) {
interesting = true
}
// XXX "no longer referenced"
if !interesting {
continue
}
// anode can potentially contribute to -δA
// - tree: expand and queue its children
// - bucket: -δA += anode
switch node := anode.node.(type) {
case *Tree:
err = node.PActivate(ctx); if err != nil { return nil, err }
defer node.PDeactivate()
// empty tree - do not expand into bucket - only process tracked holes
if len(node.Entryv()) == 0 {
// XXX dup wrt bucket processing?
δA := map[Key]ΔValue{}
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)
}
*/
anode.done = true
continue
}
av.Expand(anode)
case *Bucket:
δA, err := diffB(ctx, node, nil)
if err != nil {
return nil, err
}
// XXX also extract holes
// δ <- δA
err = δMerge(δ, δA)
if err != nil {
return nil, err
}
/*
// Adone <- δA
// Bqueue <- δA
for k_ := range δA {
Adone.Add(k_)
if !Bdone.Has(k_) {
Bqueue.Add(k_)
}
}
*/
anode.done = true
}
/*
anode, ok, err := av.GetToLeaf(ctx, k)
if err != nil {
return nil, err
}
if !ok {
// FIXME -> key must be included into some node.hole
continue // key not covered
}
// XXX check for anode.node.(*Tree) (ø tree case)
// - bucket if that bucket is reached for the first time
if !anode.done {
δA, err := diffB(ctx, anode.node.(*Bucket), nil)
if err != nil {
return nil, err
}
// XXX also extract holes
// δ <- δA
err = δMerge(δ, δA)
if err != nil {
return nil, err
}
// Adone <- δA
// Bqueue <- δA
for k_ := range δA {
Adone.Add(k_)
if !Bdone.Has(k_) {
Bqueue.Add(k_)
}
}
anode.done = true
}
// k is not there -> -[k]ø
if !Adone.Has(k) {
// XXX do we need to add(?) [k]ø->ø ?
Adone.Add(k)
}
*/
tracef(" av: %s\n", av)
}
/*
// B queue
// expand keys from new δA -> in B till buckets;
// process B buckets that cover new keys into δ+
Aqueue = SetKey{}
for k := range Bqueue {
tracef(" B [%v]\n", k)
bnode, ok, err := bv.GetToLeaf(ctx, k)
if err != nil {
return nil, err
}
if !ok {
// FIXME -> key must be included into some node.hole
continue // key not covered
}
// +bucket if that bucket is reached for the first time
if !bnode.done {
var δB map[Key]ΔValue
bbucket, ok := bnode.node.(*Bucket)
if ok { // !ok means ø tree
δB, err = diffB(ctx, nil, bbucket)
if err != nil {
return nil, err
}
}
// δ <- δB
err = δMerge(δ, δB)
if err != nil {
return nil, err
}
// Bdone <- δB
// Aqueue <- δB
for k_ := range δB {
Bdone.Add(k_)
if !Adone.Has(k_) {
Aqueue.Add(k_)
}
}
bnode.done = true
}
// k is not there -> +[k]ø
if !Bdone.Has(k) {
δB := map[Key]ΔValue{k: {VDEL, VDEL}} // [k]ø->ø
err = δMerge(δ, δB); if err != nil { return nil, err }
Bdone.Add(k)
}
tracef(" 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
}
}
}
*/
}
return δ, nil
}
func __diffT(ctx context.Context, a, b *Tree, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack) (δ map[Key]ΔValue, err error) {
tracef(" diffT %s %s\n", xidOf(a), xidOf(b))
defer xerr.Contextf(&err, "diffT %s %s", xidOf(a), xidOf(b))
......@@ -1884,7 +1545,7 @@ func pop(nodeStk *[]*nodeInRange) *nodeInRange {
}
const debug = true
const debug = false
func tracef(format string, argv ...interface{}) {
if debug {
fmt.Printf(format, argv...)
......
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