Commit 07981138 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 9d3483ba
......@@ -348,6 +348,7 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
fmt.Printf("\nUpdate δZ: %v\n", δZ.Changev)
fmt.Printf("trackIdx: %v\n", δBtail.trackIdx)
/*
// {} root -> {oid} changed under that root in tracked set
// XXX dumb -> rework to toposort and getting root from tops only
rootOf := func(node zodb.Oid) (root zodb.Oid, ok bool) {
......@@ -378,11 +379,13 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
δZT.Add(oid)
}
fmt.Println("δZByRoot:", δZByRoot)
*/
δZTC, δtopsByRoot := δBtail.δZConnectTracked(δZ)
δB := ΔB{Rev: δZ.Tid, ByRoot: make(map[zodb.Oid]map[Key]ΔValue)}
// skip opening DB connections if there is no change to any tree node
if len(δZByRoot) == 0 {
if len(δtopsByRoot) == 0 {
return δB, nil
}
......@@ -399,8 +402,10 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
return ΔB{}, err
}
for root, δZT := range δZByRoot {
δT, err := treediff(ctx, root, δZT, δBtail.trackIdx, zconnOld, zconnNew)
// for root, δZT := range δZByRoot {
for root, δtops := range δtopsByRoot {
// δT, err := treediff(ctx, root, δZT, δBtail.trackIdx, zconnOld, zconnNew)
δT, err := treediff(ctx, root, δtops, δZTC, δBtail.trackIdx, zconnOld, zconnNew)
if err != nil {
return ΔB{}, err
}
......@@ -431,24 +436,93 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
*/
}
// δZConnectTracked computes connected closure of δZ/T.
//
// δZ - all changes in a ZODB transaction.
// δZ/T - subset of those changes intersection with tracking set.
// δZ/TC - connected closure for δZ/T
//
// for example for e.g. t₀->t₁->b₂ if δZ/T={t₀ b₂} -> δZ/TC=δZ/T+{t₁}
//
// δtopsByRoot = {} root -> {top changed nodes in that tree}
func (δBtail *ΔBtail) δZConnectTracked(δZv *zodb.EventCommit) (δZTC SetOid, δtopsByRoot map[zodb.Oid]SetOid) {
δZ := SetOid{}
δZTC = SetOid{}
δtopsByRoot = map[zodb.Oid]SetOid{}
for _, δ := range δZv.Changev {
δZ.Add(δ)
}
for δ := range δZ {
track, ok := δBtail.trackIdx[δ]
if !ok {
continue // not tracked at all
}
δZTC.Add(δ)
// go up by .parent till root or till another tracked node in the tree
// if root -> δtopsByRoot[root] += δ
// if !root -> δZTC += path through which we reached another node (forming connection)
path := []zodb.Oid{}
node := δ
parent := track.parent
for {
// reached root
if parent == zodb.InvalidOid {
root := node
δtops, ok := δtopsByRoot[root]
if !ok {
δtops = SetOid{}
δtopsByRoot[root] = δtops
}
δtops.Add(δ)
break
}
// reached another tracked node
if δZ.Has(parent) {
for _, δp := range path {
δZTC.Add(δp)
}
break
}
path = append(path, parent)
trackUp, ok := δBtail.trackIdx[parent]
if !ok {
panicf("BUG: .p%s -> %s, but %s is not tracked", node, parent, parent)
}
node = parent
parent = trackUp.parent
}
}
return δZTC, δtopsByRoot
}
// treediff computes δT for tree specified by root in between old..new.
//
// XXX only for tracked
// δZT is δZ/T - subset of δZ(old..new) that touches tracked nodes of T.
func treediff(ctx context.Context, root zodb.Oid, δZT SetOid, trackIdx map[zodb.Oid]nodeTrack, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, err error) {
//func treediff(ctx context.Context, root zodb.Oid, δZT SetOid, trackIdx map[zodb.Oid]nodeTrack, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, err error) {
func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, err error) {
defer xerr.Contextf(&err, "treediff %s..%s %s", zconnOld.At(), zconnNew.At(), root)
// XXX zconnX -> a, b ?
fmt.Printf("treediff %s δZT: %v\n", root, δZT)
fmt.Printf("treediff %s δtops: %v δZTC: %v\n", root, δtops, δZTC)
defer fmt.Printf("\n")
/*
// XXX δZT -> δZTC (all changed nodes are connected)
// e.g. t₀->t₁->b₂ δZ={t₀ b₂} -> δZC=δZ+{t₁}
δZTC := δZT // FIXME stub
*/
δT = map[Key]ΔValue{}
for top := range δZT { // XXX -> sorted?
for top := range δtops { // XXX -> sorted?
a, err1 := zgetNode(ctx, zconnOld, top)
b, err2 := zgetNode(ctx, zconnNew, top)
err := xerr.Merge(err1, err2)
......
......@@ -756,6 +756,7 @@ func TestΔBTail(t *testing.T) {
// test known cases going through tree1 -> tree2 -> ...
testv := []interface{} {
"T2/B1:a-B2:c", "T2,3/B1:a-B2:c-B3:c",
///*
"T/B:",
......
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