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 ...@@ -379,7 +379,23 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid
return δT, nil 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. // 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). // δ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 ...@@ -389,6 +405,8 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid) (δ map[Key]Value, err
panic("different trees") panic("different trees")
} }
// XXX a/b = nil - means del/add -> handle
err = a.PActivate(ctx); if err != nil { return nil, err } err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate() defer a.PDeactivate()
err = b.PActivate(ctx); if err != nil { return nil, err } 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 ...@@ -402,48 +420,60 @@ func diffT(ctx context.Context, a, b *Tree, δZTC SetOid) (δ map[Key]Value, err
// //
// [0].Key = -∞ ; always returned so // [0].Key = -∞ ; always returned so
// [len(ev)].Key = +∞ ; should be assumed so // [len(ev)].Key = +∞ ; should be assumed so
aChildren := SetOid{} aChildren := map[zodb.Oid]Node{}
bChildren := SetOid{} bChildren := map[zodb.Oid]Node{}
for _, __ := range av { aChildren.Add(__.Child().POid()) } // InvalidOid = embedded bucket allChildren := SetOid{}
for _, __ := range bv { bChildren.Add(__.Child().POid()) } // ----//---- for _, __ := range av {
allChildren := SetOid{}; allChildren.Update(aChildren); allChildren.Update(bChildren) child := __.Child()
aChildren[child.POid()] = child // InvalidOid = embedded bucket
del := SetOid{} allChildren.Add(child.POid())
add := SetOid{} }
mod := SetOid{} 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 // add/del/modify, but child is not tracked - ignore
if !δZTC.Has(child) { if !δZTC.Has(child) {
continue continue
} }
ina := aChildren.Has(child) ca := aChildren[child]
inb := bChildren.Has(child) cb := bChildren[child]
switch {
case ina && inb: mod.Add(child) δc, err := diffX(ctx, ca, cb, δZTC)
case ina: del.Add(child) if err != nil {
case inb: add.Add(child) return nil, err
default: panic("unreachable")
} }
}
for child := range del { // XXX sorted ? // merge δ <- δc
δc, err := delChild(ctx, child, δZTC) // -> removal + remove child and its children from tracked for k, v := range δc {
// XXX err vprev, already := δ[k]
} if !already {
for child := range add { // XXX sorted ? δ[k] = v
δc, err := addChild(ctx, child, δZTC) // -> addd + add child and its children into tracked } else {
} // both δ and δc has [k] - it can be that key
for child := range mod { // XXX sorted ? // 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 return δ, nil
} }
// diffB computes difference in between two revisions of a bucket. // 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) { func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]Value, err error) {
defer xerr.Contextf(&err, "diffB %s", a.POid()) 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) // 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) { ...@@ -451,6 +481,8 @@ func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]Value, err error) {
panic("different buckets") panic("different buckets")
} }
// XXX a/b = nil - means del/add -> handle
err = a.PActivate(ctx); if err != nil { return nil, err } err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate() defer a.PDeactivate()
err = b.PActivate(ctx); if err != nil { return nil, err } 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