Commit 5d73770d authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6df31f29
...@@ -218,7 +218,8 @@ type ΔTree struct { ...@@ -218,7 +218,8 @@ type ΔTree struct {
// XXX is a set of PP(leafs) nodes XXX -> PTreeSubSet ? TreePSubSet ? TreePPSet ? PPSubSet ? // XXX is a set of PP(leafs) nodes XXX -> PTreeSubSet ? TreePSubSet ? TreePPSet ? PPSubSet ?
// XXX PPNodeSet? TreePPSubSet ? // XXX PPNodeSet? TreePPSubSet ? PPSet? PPNodeSet? PPOidSet?
// ~~ PPOidSet ~~ <- Y
// //
// where PP maps a leaf to {leaf, leaf.parent, leaf.parent.parent, ...} up to // where PP maps a leaf to {leaf, leaf.parent, leaf.parent.parent, ...} up to
// top root node from where the leaf is reached. // top root node from where the leaf is reached.
...@@ -228,7 +229,7 @@ type ΔTree struct { ...@@ -228,7 +229,7 @@ type ΔTree struct {
// XXX place // XXX place
type trackIndex map[zodb.Oid]*nodeTrack type trackIndex map[zodb.Oid]*nodeTrack
// XXX place XXX PTreeSubSetNode ? // XXX place XXX PTreeSubSetNode ? PPNode? nodeP? nodePnC ?
// nodeTrack represents tracking information about a node. // nodeTrack represents tracking information about a node.
type nodeTrack struct { type nodeTrack struct {
parent zodb.Oid // parent node | InvalidOid for root parent zodb.Oid // parent node | InvalidOid for root
...@@ -239,15 +240,20 @@ type nodeTrack struct { ...@@ -239,15 +240,20 @@ type nodeTrack struct {
*/ */
} }
// δtrackIndex represents change to trackIndex. // δtrackIndex represents change to trackIndex. XXX name
//
// The result B of applying δ to A is:
//
// B = A.Difference(δ.Del).Union(δ.Add)
// XXX place // XXX place
type δtrackIndex struct { type δtrackIndex struct {
/*
// set of leaf nodes to remove. After leafs are removed, their parents // set of leaf nodes to remove. After leafs are removed, their parents
// are automatically cleaned down-up. Removals are processed before // are automatically cleaned down-up. Removals are processed before
// adds (see below). // adds (see below).
DelLeaf SetOid DelLeaf SetOid
*/
// nodes to add XXX -> add/modify ? Del trackIndex
Add trackIndex Add trackIndex
} }
...@@ -326,82 +332,40 @@ func (tidx trackIndex) verify() { ...@@ -326,82 +332,40 @@ func (tidx trackIndex) verify() {
// //
// In other words it removes B nodes from A while still maintaining A as P-connected. // In other words it removes B nodes from A while still maintaining A as P-connected.
func (A trackIndex) DifferenceInplace(B trackIndex) { func (A trackIndex) DifferenceInplace(B trackIndex) {
//fmt.Printf("\n\nDifferenceInplace:\n") fmt.Printf("\n\nDifferenceInplace:\n")
//fmt.Printf("A: %s\n", A) fmt.Printf(" A: %s\n", A)
//fmt.Printf("B: %s\n", B) fmt.Printf(" B: %s\n", B)
defer fmt.Printf("->D: %s\n", A)
A.verify() A.verify()
B.verify() B.verify()
defer A.verify() defer A.verify()
panic("TODO")
}
// UnionInplace sets A = PP(A.leafs | B.leafs) δnchild := map[zodb.Oid]int{}
//
// In other words it adds B nodes to A.
func (A trackIndex) UnionInplace(B trackIndex) {
//fmt.Printf("\n\nUnionInplace:\n")
//fmt.Printf("A: %s\n", A)
//fmt.Printf("B: %s\n", B)
A.verify()
B.verify()
defer A.verify()
// remove B.leafs and thier parents
for oid, t2 := range B { for oid, t2 := range B {
t, already := A[oid] if t2.nchild != 0 {
if !already { continue // not a leaf
t = &nodeTrack{parent: t2.parent, nchild: t2.nchild}
A[oid] = t
} else {
if t2.parent != t.parent {
// XXX or verify this at Track time and require
// that update is passed only entries with the
// same .parent? (then it would be ok to panic here)
// XXX -> error (e.g. due to corrupt data in ZODB)
panicf("node %s is reachable from multiple parents: %s %s",
oid, t.parent, t2.parent)
}
t.nchild += t2.nchild
if t.parent != zodb.InvalidOid {
// this node is already present in both trees
// compensate for that in its parent (which must be present)
A[t.parent].nchild--
}
} }
}
}
// ApplyΔ applies δ to trackIdx. XXX
func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) {
//fmt.Printf("\n\nApplyΔ\n")
//fmt.Printf("\ttidx: %v\n", tidx)
//fmt.Printf("\tDelLeaf: %v\n", δ.DelLeaf)
//fmt.Printf("\tAdd: %v\n", δ.Add)
//defer fmt.Printf("\n\t-> tidx: %v\n", tidx)
tidx.verify()
δnchild := map[zodb.Oid]int{} t, present := A[oid]
// remove leafs and thier parents
for leaf := range δ.DelLeaf {
t, present := tidx[leaf]
if !present { if !present {
continue // already not there continue // already not there
} }
delete(tidx, leaf) // XXX assert t.parent == t2.parent ?
delete(A, oid)
if t.parent != zodb.InvalidOid { if t.parent != zodb.InvalidOid {
δnchild[t.parent] -= 1 δnchild[t.parent] -= 1
} }
} }
/* XXX kill
// process adds // process adds
for oid, δt := range δ.Add { for oid, δt := range δ.Add {
t, already := tidx[oid] t, already := A[oid]
if already { if already {
if t.parent != zodb.InvalidOid { if t.parent != zodb.InvalidOid {
δnchild[t.parent] -= 1 δnchild[t.parent] -= 1
...@@ -409,18 +373,19 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) { ...@@ -409,18 +373,19 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) {
} }
} else { } else {
t = &nodeTrack{parent: δt.parent, nchild: 0} t = &nodeTrack{parent: δt.parent, nchild: 0}
tidx[oid] = t A[oid] = t
} }
if t.parent != zodb.InvalidOid { if t.parent != zodb.InvalidOid {
δnchild[t.parent] += 1 // remeber to nchild++ in parent δnchild[t.parent] += 1 // remeber to nchild++ in parent
} }
} }
*/
// perform scheduled δnchild adjustment // perform scheduled δnchild adjustment
gcq := []zodb.Oid{} gcq := []zodb.Oid{}
for oid, δnc := range δnchild { for oid, δnc := range δnchild {
t := tidx[oid] // XXX t can be nil -> XXX no must be there as tidx is connected t := A[oid] // XXX t can be nil -> XXX no must be there as A is connected
t.nchild += δnc t.nchild += δnc
if t.nchild == 0 && /* not root node */t.parent != zodb.InvalidOid { if t.nchild == 0 && /* not root node */t.parent != zodb.InvalidOid {
gcq = append(gcq, oid) gcq = append(gcq, oid)
...@@ -429,10 +394,64 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) { ...@@ -429,10 +394,64 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) {
// GC parents that became to have .nchild == 0 // GC parents that became to have .nchild == 0
for _, oid := range gcq { for _, oid := range gcq {
tidx.gc1(oid) A.gc1(oid)
} }
}
// UnionInplace sets A = PP(A.leafs | B.leafs)
//
// In other words it adds B nodes to A.
func (A trackIndex) UnionInplace(B trackIndex) {
fmt.Printf("\n\nUnionInplace:\n")
fmt.Printf(" A: %s\n", A)
fmt.Printf(" B: %s\n", B)
defer fmt.Printf("->U: %s\n", A)
A.verify()
B.verify()
defer A.verify()
for oid, t2 := range B {
t, already := A[oid]
if !already {
t = &nodeTrack{parent: t2.parent, nchild: t2.nchild}
A[oid] = t
} else {
if t2.parent != t.parent {
// XXX or verify this at Track time and require
// that update is passed only entries with the
// same .parent? (then it would be ok to panic here)
// XXX -> error (e.g. due to corrupt data in ZODB)
panicf("node %s is reachable from multiple parents: %s %s",
oid, t.parent, t2.parent)
}
t.nchild += t2.nchild
if t.parent != zodb.InvalidOid {
// this node is already present in both trees
// compensate for that in its parent (which must be present)
A[t.parent].nchild--
}
}
}
}
// ApplyΔ applies δ to trackIdx. XXX
func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) {
fmt.Printf("\n\nApplyΔ\n")
fmt.Printf(" A: %s\n", tidx)
fmt.Printf(" -: %s\n", δ.Del)
fmt.Printf(" +: %s\n", δ.Add)
defer fmt.Printf("\n->B: %s\n", tidx)
tidx.verify() tidx.verify()
δ.Del.verify()
δ.Add.verify()
defer tidx.verify()
tidx.DifferenceInplace(δ.Del)
tidx.UnionInplace(δ.Add)
} }
// treeSetKey represents ordered set of keys. // treeSetKey represents ordered set of keys.
...@@ -601,6 +620,28 @@ func (δBtail *ΔBtail) holeIdxFor(root zodb.Oid) treeSetKey { ...@@ -601,6 +620,28 @@ func (δBtail *ΔBtail) holeIdxFor(root zodb.Oid) treeSetKey {
return holeIdx return holeIdx
} }
// Path returns path leading to node speficied by oid.
//
// The node must be in the set.
// XXX place
func (tidx trackIndex) Path(oid zodb.Oid) (path []zodb.Oid) {
for {
t, ok := tidx[oid]
if !ok {
panicf("node %s is not in the set <- %v", oid, path)
}
path = append([]zodb.Oid{oid}, path...)
oid = t.parent
if oid == zodb.InvalidOid {
break
}
}
return path
}
// XXX place // XXX place
// XXX doc // XXX doc
func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = root func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = root
...@@ -615,6 +656,9 @@ func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = ...@@ -615,6 +656,9 @@ func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] =
} }
func (tidx trackIndex) AddPath(path []zodb.Oid) { func (tidx trackIndex) AddPath(path []zodb.Oid) {
tidx.verify()
defer tidx.verify()
l := len(path) l := len(path)
if l == 0 { if l == 0 {
panic("empty path") panic("empty path")
...@@ -1140,6 +1184,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -1140,6 +1184,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
} }
// adjust trackIdx by merge(δtrackTops) // adjust trackIdx by merge(δtrackTops)
/*
δtrack := &δtrackIndex{DelLeaf: SetOid{}, Add: trackIndex{}} δtrack := &δtrackIndex{DelLeaf: SetOid{}, Add: trackIndex{}}
for _, δ := range δtrackv { for _, δ := range δtrackv {
δtrack.DelLeaf.Update(δ.DelLeaf) δtrack.DelLeaf.Update(δ.DelLeaf)
...@@ -1147,6 +1192,12 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -1147,6 +1192,12 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
δtrack.Add[oid] = t // XXX verify changes from 2 δtrackTops are consistent δtrack.Add[oid] = t // XXX verify changes from 2 δtrackTops are consistent
} }
} }
*/
δtrack := &δtrackIndex{Del: trackIndex{}, Add: trackIndex{}}
for _, δ := range δtrackv {
δtrack.Del.UnionInplace(δ.Del)
δtrack.Add.UnionInplace(δ.Add)
}
trackIdx.ApplyΔ(δtrack) trackIdx.ApplyΔ(δtrack)
return δT, nil return δT, nil
...@@ -1221,7 +1272,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1221,7 +1272,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
if B == nil { panic("B is nil") } if B == nil { panic("B is nil") }
δ = map[Key]ΔValue{} δ = map[Key]ΔValue{}
δtrack = &δtrackIndex{DelLeaf: SetOid{}, Add: trackIndex{}} // δtrack = &δtrackIndex{DelLeaf: SetOid{}, Add: trackIndex{}}
δtrack = &δtrackIndex{Del: trackIndex{}, Add: trackIndex{}}
defer tracef(" -> δ: %v\n", δ) defer tracef(" -> δ: %v\n", δ)
// path prefix to A and B // path prefix to A and B
...@@ -1261,7 +1313,9 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1261,7 +1313,9 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
// XXX // XXX
// XXX requires A.oid == B.oid // XXX requires A.oid == B.oid
// XXX -> trackIndex // XXX -> trackIndex
BtrackIdx := map[zodb.Oid]nodeTrack{B.POid(): nodeTrack{parent: trackIdx[B.POid()].parent}} // BtrackIdx := map[zodb.Oid]nodeTrack{B.POid(): nodeTrack{parent: trackIdx[B.POid()].parent}}
BtrackIdx := trackIndex{}
BtrackIdx.AddPath(trackIdx.Path(B.POid()))
// phase 1: expand A top->down driven by δZTC. // phase 1: expand A top->down driven by δZTC.
// by default a node contributes to δ- // by default a node contributes to δ-
...@@ -1284,7 +1338,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1284,7 +1338,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
// a is bucket -> δ- // a is bucket -> δ-
δA, err := diffB(ctx, a, nil); /*X*/if err != nil { return nil,nil, err } δA, err := diffB(ctx, a, nil); /*X*/if err != nil { return nil,nil, err }
err = δMerge(δ, δA); /*X*/if err != nil { return nil,nil, err } err = δMerge(δ, δA); /*X*/if err != nil { return nil,nil, err }
δtrack.DelLeaf.Add(a.POid()) // δtrack.DelLeaf.Add(a.POid())
δtrack.Del.AddPath(ra.Path())
// Bkqueue <- δA // Bkqueue <- δA
for k := range δA { for k := range δA {
...@@ -1341,7 +1396,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1341,7 +1396,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
bchildren := Bv.Expand(blo) bchildren := Bv.Expand(blo)
for _, bc := range bchildren { for _, bc := range bchildren {
bcOid := bc.node.POid() bcOid := bc.node.POid()
BtrackIdx[bcOid] = nodeTrack{parent: blo.node.POid()} // BtrackIdx[bcOid] = nodeTrack{parent: blo.node.POid()}
BtrackIdx.AddPath(bc.Path())
if acOid == bcOid { if acOid == bcOid {
found = true found = true
} }
...@@ -1356,6 +1412,14 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1356,6 +1412,14 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
// XXX Bkqueue <- holes(ac.range \ bc.range) XXX test for this // XXX Bkqueue <- holes(ac.range \ bc.range) XXX test for this
// adjust trackIdx since path to the node could have changed // adjust trackIdx since path to the node could have changed
apath := trackIdx.Path(acOid)
bpath := BtrackIdx.Path(acOid)
if !reflect.DeepEqual(apath, bpath) {
δtrack.Del.AddPath(apath)
δtrack.Add.AddPath(bpath)
}
/* XXX kill
oid := acOid oid := acOid
for oid != zodb.InvalidOid { for oid != zodb.InvalidOid {
told := trackIdx[oid] told := trackIdx[oid]
...@@ -1364,11 +1428,12 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1364,11 +1428,12 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
break break
} }
if told == nil || (told.parent != tnew.parent) { if told == nil || (told.parent != tnew.parent) {
δtrack.Add[oid] = &tnew // XXX adjust nchildren δtrack.Add.AddPath(BtrackIdx.Path(oid))
} }
oid = tnew.parent oid = tnew.parent
} }
*/
continue continue
} }
...@@ -1453,7 +1518,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -1453,7 +1518,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
// δ <- δA // δ <- δA
err = δMerge(δ, δA); /*X*/if err != nil { return nil,nil, err } err = δMerge(δ, δA); /*X*/if err != nil { return nil,nil, err }
δtrack.DelLeaf.Add(a.node.POid()) // δtrack.DelLeaf.Add(a.node.POid())
δtrack.Del.AddPath(a.Path())
// Bkqueue <- δA // Bkqueue <- δA
for k_ := range δA { for k_ := range δA {
......
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