Commit 62bd1f5e authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6b1e072b
...@@ -209,8 +209,13 @@ func (δBtail *ΔBtail) Track(path []Node, flags TrackFlags) { // XXX Tree|Bucke ...@@ -209,8 +209,13 @@ func (δBtail *ΔBtail) Track(path []Node, flags TrackFlags) { // XXX Tree|Bucke
// XXX assert Tree Tree ... Tree Bucket // XXX assert Tree Tree ... Tree Bucket
root := treeRoot.POid() root := treeRoot.POid()
oidv := []Oid{}
for _, node := range path { oidv = append(oidv, node.POid()) }
fmt.Printf("Track %v\n", oidv)
for _, node := range path { for _, node := range path {
oid := node.POid() oid := node.POid()
// XXX check for InvalidOid (e.g. T/B1:a with bucket not having its own oid.
nodeRoots, ok := δBtail.trackIdx[oid] nodeRoots, ok := δBtail.trackIdx[oid]
if !ok { if !ok {
nodeRoots = make(SetOid) nodeRoots = make(SetOid)
...@@ -325,11 +330,14 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid ...@@ -325,11 +330,14 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid
fmt.Printf("treediff %s δZT: %v\n", root, δZT) fmt.Printf("treediff %s δZT: %v\n", root, δZT)
// XXX δZT -> δZT* (all changed nodes are connected)
// e.g. t₀->t₁->b₂ δZ={t₀ b₂} -> δZ*=δZ+{t₁}
δT = map[Key]Value{} δT = map[Key]Value{}
for oid := range δZT { for top := range δZT { // XXX -> for each top-level nodes in δZT*
xa, err1 := zconnOld.Get(ctx, oid) xa, err1 := zconnOld.Get(ctx, top)
xb, err2 := zconnNew.Get(ctx, oid) xb, err2 := zconnNew.Get(ctx, top)
err := xerr.Merge(err1, err2) err := xerr.Merge(err1, err2)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -338,40 +346,101 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid ...@@ -338,40 +346,101 @@ func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid
ta := zodb.ClassOf(xa) ta := zodb.ClassOf(xa)
tb := zodb.ClassOf(xb) tb := zodb.ClassOf(xb)
if ta != tb { if ta != tb {
return nil, fmt.Errorf("object %s: type mutated: %s -> %s", oid, ta, tb) return nil, fmt.Errorf("object %s: type mutated: %s -> %s", top, ta, tb)
} }
// XXX activate/deactivate // XXX activate/deactivate
var δtop map[Key]Value
switch a := xa.(type) { switch a := xa.(type) {
default: default:
return nil, fmt.Errorf("object %s: type unexpected: %s", oid, ta) return nil, fmt.Errorf("object %s: type unexpected: %s", top, ta)
case *Tree:
fmt.Printf(" T%s\n", a.POid())
b := xb.(*Tree) // must not fail
δtop, err = diffT(ctx, a, b, δZT*)
case *Bucket: case *Bucket:
fmt.Printf(" B%s\n", a.POid())
b := xb.(*Bucket) // must not fail b := xb.(*Bucket) // must not fail
δb, err := diffB(ctx, a, b) δtop, err = diffB(ctx, a, b)
if err != nil { }
return nil, err
}
for k,v := range δb {
δT[k] = v
}
// XXX stub if err != nil {
case *Tree: return nil, err
b := xb.(*Tree) // must not fail }
// TODO handle for k,v := range δtop {
_ = b δT[k] = v
} }
} }
return δT, nil return δT, nil
} }
// diffT computes difference in between two revisions of substree.
// δZTC is connected set of objects covering δZT (objects changed in this tree)
func diffT(ctx context.Context, a, b *Tree, δZTC SetOid) (δ map[Key]Value, err error) {
defer xerr.Contextf(&err, "diffT %s", a.POid())
if a.POid() != b.POid() {
panic("different trees")
}
err = a.PActivate(ctx); if err != nil { return nil, err }
defer a.PDeactivate()
err = b.PActivate(ctx); if err != nil { return nil, err }
defer b.PDeactivate()
av := a.Entryv() // key↑
bv := b.Entryv() // key↑
δ = map[Key]Value{}
// [i].Key ≤ [i].Child.*.Key < [i+1].Key i ∈ [0, len([]))
//
// [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{}
for child := range allChildren {
// 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")
}
}
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 ?
}
}
// diffB computes difference in between two revisions of a bucket. // diffB computes difference in between two revisions of a bucket.
// the buckets must be already activated
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)
if a.POid() != b.POid() { if a.POid() != b.POid() {
panic("different buckets") panic("different buckets")
} }
......
...@@ -567,6 +567,8 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, ...@@ -567,6 +567,8 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
} }
} }
// XXX verify δbtail index consistency against @at1
// δB <- δZ // δB <- δZ
δB, err := δbtail.Update(δZ); X(err) δB, err := δbtail.Update(δZ); X(err)
if δB.Rev != δZ.Tid { if δB.Rev != δZ.Tid {
...@@ -574,6 +576,8 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, ...@@ -574,6 +576,8 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
return return
} }
// XXX verify δbtail index consistency against @at2
// assert δB.ByRoot == {treeRoot -> ...} if inδTOK != ø // assert δB.ByRoot == {treeRoot -> ...} if inδTOK != ø
// == ø if inδTOK == ø // == ø if inδTOK == ø
......
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