Commit 9fa6ad5e authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 58af93ce
......@@ -379,7 +379,23 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid
return δT, nil
}
// diffT computes difference in between two revisions of a tree's substree.
// diffX computes difference in between two revisions of a tree's subtree.
//
// a, b point to top of the subtree @old and @new revisions and must be of the
// same type - tree or bucket.
//
// δZTC is connected set of objects covering δZT (objects changed in this tree in old..new).
//
// a/b can be = nil; a=nil means addition, b=nil means deletion.
func diffX(ctx context.Context, a, b Node, δZTC SetOid) (δ map[Key]Value, err error) {
if (a==nil && b==nil) {
panic("BUG: both a & b == nil")
}
panic("TODO")
}
// diffT computes difference in between two revisions of a tree's subtree.
//
// a, b point to top of the subtree @old and @new revisions.
// δZTC is connected set of objects covering δZT (objects changed in this tree in old..new).
......@@ -389,6 +405,8 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid) (δ map[Key]Value, err
panic("different trees")
}
// XXX a/b = nil - means del/add -> handle
err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate()
err = b.PActivate(ctx); if err != nil { return nil, err }
......@@ -402,48 +420,60 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid) (δ map[Key]Value, err
//
// [0].Key = -∞ ; always returned so
// [len(ev)].Key = +∞ ; should be assumed so
aChildren := SetOid{}
bChildren := SetOid{}
for _, __ := range av { aChildren.Add(__.Child().POid()) } // InvalidOid = embedded bucket
for _, __ := range bv { bChildren.Add(__.Child().POid()) } // ----//----
allChildren := SetOid{}; allChildren.Update(aChildren); allChildren.Update(bChildren)
del := SetOid{}
add := SetOid{}
mod := SetOid{}
aChildren := map[zodb.Oid]Node{}
bChildren := map[zodb.Oid]Node{}
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 {
for child := range allChildren { // XXX -> sorted?
// add/del/modify, but child is not tracked - ignore
if !δZTC.Has(child) {
continue
}
ina := aChildren.Has(child)
inb := bChildren.Has(child)
switch {
case ina && inb: mod.Add(child)
case ina: del.Add(child)
case inb: add.Add(child)
default: panic("unreachable")
ca := aChildren[child]
cb := bChildren[child]
δc, err := diffX(ctx, ca, cb, δZTC)
if err != nil {
return nil, err
}
}
for child := range del { // XXX sorted ?
δc, err := delChild(ctx, child, δZTC) // -> removal + remove child and its children from tracked
// XXX err
}
for child := range add { // XXX sorted ?
δc, err := addChild(ctx, child, δZTC) // -> addd + add child and its children into tracked
}
for child := range mod { // XXX sorted ?
// merge δ <- δc
for k, v := range δc {
vprev, already := δ[k]
if !already {
δ[k] = v
} else {
// both δ and δc has [k] - it can be that key
// entry migrated from one bucket into another.
if (vprev == VDEL && v == VDEL) || (vprev != VDEL && v != VDEL) {
return nil, fmt.Errorf("BUG or btree corrupt: [%v] has " +
"duplicate entries: %v, %v", k, vprev, v)
}
if v != VDEL {
δ[k] =v
}
}
}
// XXX process keys from δ outside of already tracked nodes
}
return δ, nil
}
// diffB computes difference in between two revisions of a bucket.
// see diffX for details.
func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]Value, err error) {
defer xerr.Contextf(&err, "diffB %s", a.POid())
// XXX oid can be InvalidOid for T/B... (i.e. B is part of T and is not yet committed separately)
......@@ -451,6 +481,8 @@ func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]Value, err error) {
panic("different buckets")
}
// XXX a/b = nil - means del/add -> handle
err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate()
err = b.PActivate(ctx); if err != nil { return nil, err }
......
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