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

.

parent ac3bb8cc
...@@ -27,41 +27,37 @@ import ( ...@@ -27,41 +27,37 @@ import (
) )
// XXX is a set of PP(leafs) nodes XXX -> PTreeSubSet ? TreePSubSet ? TreePPSet ? PPSubSet ? // PPTreeSubSet repesents PP-connected subset of tree node objects.
// XXX PPNodeSet? TreePPSubSet ? PPSet? PPNodeSet? PPOidSet?
// ~~ PPOidSet ~~ <- N
// //
// YYY: // where PP(node) maps node to {node, node.parent, leaf.parent,parent, ...} up
// XXX PPTreeNodeSet // to top root from where the node is reached.
// XXX PPTreeNodeObjSet
// XXX PPTreeNodeOidSet
// XXX PPTreeObjSet
// XXX PPTreeOidSet
// //
// where PP maps a leaf to {leaf, leaf.parent, leaf.parent.parent, ...} up to // The nodes in the set are represented by their Oid.
// top root node from where the leaf is reached.
// //
// Every node in the set also has .parent pointer. // Usually PPTreeSubSet is built as PP(some-leafs), but in general the starting
// nodes are arbitrary. PPTreeSubSet can also have many root nodes, thus not
// necessarily representing a subset of a single tree.
// //
// XXX place // Usual set operations are provided: Union, Difference and Intersection.
type trackIndex map[zodb.Oid]*nodeTrack //
// Nodes can be added into the set via AddPath. Path is reverse operation - it
// returns path to tree node given node oid.
//
// XXX ΔPPTreeSubSet
//
// Every node in the set also has .parent pointer.
type PPTreeSubSet map[zodb.Oid]*nodeInTree
// XXX place XXX PTreeSubSetNode ? PPNode? nodeP? nodePnC ? // nodeInTree represents tracking information about a node.
// nodeTrack represents tracking information about a node. type nodeInTree struct {
type nodeTrack struct {
parent zodb.Oid // parent node | InvalidOid for root parent zodb.Oid // parent node | InvalidOid for root
nchild int // number of direct children in trackIdx referring to this node nchild int // number of direct children in PPTreeSubSet referring to this node
// XXX + [lo,hi) range this node is coming under in its parent // XXX + [lo,hi) range this node is coming under in its parent
/*
holes SetKey // missing keys tracked under this node; nil for !leaf
// XXX move holes into separate ΔBtail..holeIdx
*/
} }
// δtrackIndex represents change to trackIndex. XXX name // ΔPPTreeSubSet represents a change to PPTreeSubSet.
// //
// XXX refer to trackIndex.ApplyΔ // It can be applied via PPTreeSubSet.ApplyΔ .
// //
// The result B of applying δ to A is: // The result B of applying δ to A is:
// //
...@@ -98,16 +94,14 @@ type nodeTrack struct { ...@@ -98,16 +94,14 @@ type nodeTrack struct {
// - xfixup(+1, δnchildNonLeafs) // - xfixup(+1, δnchildNonLeafs)
// //
// produce correctly PP-connected set. // produce correctly PP-connected set.
// type ΔPPTreeSubSet struct {
// XXX place Del PPTreeSubSet
type δtrackIndex struct { Add PPTreeSubSet
Del trackIndex
Add trackIndex
δnchildNonLeafs map[zodb.Oid]int δnchildNonLeafs map[zodb.Oid]int
} }
// Update updates δ to be combination of δ+δ2. // Update updates δ to be combination of δ+δ2.
func (δ *δtrackIndex) Update(δ2 *δtrackIndex) { func (δ *ΔPPTreeSubSet) Update(δ2 *ΔPPTreeSubSet) {
δ.Del.UnionInplace(δ2.Del) δ.Del.UnionInplace(δ2.Del)
δ.Add.UnionInplace(δ2.Add) δ.Add.UnionInplace(δ2.Add)
for oid, δnc := range δ2.δnchildNonLeafs { for oid, δnc := range δ2.δnchildNonLeafs {
...@@ -116,14 +110,14 @@ func (δ *δtrackIndex) Update(δ2 *δtrackIndex) { ...@@ -116,14 +110,14 @@ func (δ *δtrackIndex) Update(δ2 *δtrackIndex) {
} }
// Reverse changes δ=diff(A->B) to δ'=diff(A<-B). // Reverse changes δ=diff(A->B) to δ'=diff(A<-B).
func (δ *δtrackIndex) Reverse() { func (δ *ΔPPTreeSubSet) Reverse() {
δ.Del, δ.Add = δ.Add, δ.Del δ.Del, δ.Add = δ.Add, δ.Del
// δnchildNonLeafs stays the same // δnchildNonLeafs stays the same
} }
// gc1 garbage-collects oid and cleans up its parent down-up. // gc1 garbage-collects oid and cleans up its parent down-up.
func (tidx trackIndex) gc1(oid zodb.Oid) { func (tidx PPTreeSubSet) gc1(oid zodb.Oid) {
t, present := tidx[oid] t, present := tidx[oid]
if !present { if !present {
return // already not there return // already not there
...@@ -146,7 +140,7 @@ func (tidx trackIndex) gc1(oid zodb.Oid) { ...@@ -146,7 +140,7 @@ func (tidx trackIndex) gc1(oid zodb.Oid) {
} }
// verify verifies internal consistency of tidx. // verify verifies internal consistency of tidx.
func (tidx trackIndex) verify() { func (tidx PPTreeSubSet) verify() {
// XXX !debug -> return // XXX !debug -> return
var badv []string var badv []string
...@@ -196,7 +190,7 @@ func (tidx trackIndex) verify() { ...@@ -196,7 +190,7 @@ func (tidx trackIndex) verify() {
// DifferenceInplace sets A = PP(A.leafs \ B.leafs) // DifferenceInplace sets A = PP(A.leafs \ B.leafs)
// //
// 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 PPTreeSubSet) DifferenceInplace(B PPTreeSubSet) {
if debugPPSet { if debugPPSet {
fmt.Printf("\n\nDifferenceInplace:\n") fmt.Printf("\n\nDifferenceInplace:\n")
fmt.Printf(" A: %s\n", A) fmt.Printf(" A: %s\n", A)
...@@ -211,7 +205,7 @@ func (A trackIndex) DifferenceInplace(B trackIndex) { ...@@ -211,7 +205,7 @@ func (A trackIndex) DifferenceInplace(B trackIndex) {
A.xDifferenceInplace(B) A.xDifferenceInplace(B)
} }
func (A trackIndex) xDifferenceInplace(B trackIndex) { func (A PPTreeSubSet) xDifferenceInplace(B PPTreeSubSet) {
if debugPPSet { if debugPPSet {
fmt.Printf("\n\n xDifferenceInplace:\n") fmt.Printf("\n\n xDifferenceInplace:\n")
fmt.Printf(" a: %s\n", A) fmt.Printf(" a: %s\n", A)
...@@ -250,7 +244,7 @@ func (A trackIndex) xDifferenceInplace(B trackIndex) { ...@@ -250,7 +244,7 @@ func (A trackIndex) xDifferenceInplace(B trackIndex) {
A.fixup(δnchild) A.fixup(δnchild)
} }
func (A trackIndex) xUnionInplace(B trackIndex) { func (A PPTreeSubSet) xUnionInplace(B PPTreeSubSet) {
if debugPPSet { if debugPPSet {
fmt.Printf("\n\n xUnionInplace:\n") fmt.Printf("\n\n xUnionInplace:\n")
fmt.Printf(" a: %s\n", A) fmt.Printf(" a: %s\n", A)
...@@ -263,7 +257,7 @@ func (A trackIndex) xUnionInplace(B trackIndex) { ...@@ -263,7 +257,7 @@ func (A trackIndex) xUnionInplace(B trackIndex) {
for oid, t2 := range B { for oid, t2 := range B {
t, already := A[oid] t, already := A[oid]
if !already { if !already {
t = &nodeTrack{parent: t2.parent, nchild: 0} t = &nodeInTree{parent: t2.parent, nchild: 0}
A[oid] = t A[oid] = t
// remember to nchild++ in parent // remember to nchild++ in parent
if t.parent != zodb.InvalidOid { if t.parent != zodb.InvalidOid {
...@@ -286,10 +280,10 @@ func (A trackIndex) xUnionInplace(B trackIndex) { ...@@ -286,10 +280,10 @@ func (A trackIndex) xUnionInplace(B trackIndex) {
// fixup performs scheduled δnchild adjustment. // fixup performs scheduled δnchild adjustment.
// XXX place // XXX place
func (A trackIndex) fixup(δnchild map[zodb.Oid]int) { func (A PPTreeSubSet) fixup(δnchild map[zodb.Oid]int) {
A.xfixup(+1, δnchild) A.xfixup(+1, δnchild)
} }
func (A trackIndex) xfixup(sign int, δnchild map[zodb.Oid]int) { func (A PPTreeSubSet) xfixup(sign int, δnchild map[zodb.Oid]int) {
gcq := []zodb.Oid{} gcq := []zodb.Oid{}
for oid, δnc := range δnchild { for oid, δnc := range δnchild {
t := A[oid] // XXX t can be nil -> XXX no must be there as A is connected t := A[oid] // XXX t can be nil -> XXX no must be there as A is connected
...@@ -308,7 +302,7 @@ func (A trackIndex) xfixup(sign int, δnchild map[zodb.Oid]int) { ...@@ -308,7 +302,7 @@ func (A trackIndex) xfixup(sign int, δnchild map[zodb.Oid]int) {
// UnionInplace sets A = PP(A.leafs | B.leafs) // UnionInplace sets A = PP(A.leafs | B.leafs)
// //
// In other words it adds B nodes to A. // In other words it adds B nodes to A.
func (A trackIndex) UnionInplace(B trackIndex) { func (A PPTreeSubSet) UnionInplace(B PPTreeSubSet) {
if debugPPSet { if debugPPSet {
fmt.Printf("\n\nUnionInplace:\n") fmt.Printf("\n\nUnionInplace:\n")
fmt.Printf(" A: %s\n", A) fmt.Printf(" A: %s\n", A)
...@@ -324,7 +318,7 @@ func (A trackIndex) UnionInplace(B trackIndex) { ...@@ -324,7 +318,7 @@ func (A trackIndex) UnionInplace(B trackIndex) {
} }
// ApplyΔ applies δ to trackIdx. XXX // ApplyΔ applies δ to trackIdx. XXX
func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) { func (tidx PPTreeSubSet) ApplyΔ(δ *ΔPPTreeSubSet) {
if debugPPSet { if debugPPSet {
fmt.Printf("\n\nApplyΔ\n") fmt.Printf("\n\nApplyΔ\n")
fmt.Printf(" A: %s\n", tidx) fmt.Printf(" A: %s\n", tidx)
...@@ -349,7 +343,7 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) { ...@@ -349,7 +343,7 @@ func (tidx trackIndex) ApplyΔ(δ *δtrackIndex) {
// //
// The node must be in the set. // The node must be in the set.
// XXX place // XXX place
func (tidx trackIndex) Path(oid zodb.Oid) (path []zodb.Oid) { func (tidx PPTreeSubSet) Path(oid zodb.Oid) (path []zodb.Oid) {
for { for {
t, ok := tidx[oid] t, ok := tidx[oid]
if !ok { if !ok {
...@@ -369,7 +363,7 @@ func (tidx trackIndex) Path(oid zodb.Oid) (path []zodb.Oid) { ...@@ -369,7 +363,7 @@ func (tidx trackIndex) Path(oid zodb.Oid) (path []zodb.Oid) {
// XXX place // XXX place
// XXX doc // XXX doc
func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = root func (tidx PPTreeSubSet) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = root
// XXX assert Tree Tree ... Tree Bucket // XXX assert Tree Tree ... Tree Bucket
// root := path[0].(*Tree).POid() // root := path[0].(*Tree).POid()
...@@ -380,7 +374,7 @@ func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] = ...@@ -380,7 +374,7 @@ func (tidx trackIndex) AddNodePath(path []Node) { // XXX Tree|Bucket; path[0] =
tidx.AddPath(oidv) tidx.AddPath(oidv)
} }
func (tidx trackIndex) AddPath(path []zodb.Oid) { func (tidx PPTreeSubSet) AddPath(path []zodb.Oid) {
tidx.verify() tidx.verify()
defer tidx.verify() defer tidx.verify()
...@@ -397,8 +391,8 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) { ...@@ -397,8 +391,8 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) {
} }
parent := zodb.InvalidOid parent := zodb.InvalidOid
var ptrack *nodeTrack = nil var ptrack *nodeInTree = nil
var track *nodeTrack // XXX kill here var track *nodeInTree // XXX kill here
var oldTrack bool var oldTrack bool
for _, oid := range path { for _, oid := range path {
if oid == zodb.InvalidOid { if oid == zodb.InvalidOid {
...@@ -407,7 +401,7 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) { ...@@ -407,7 +401,7 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) {
track, oldTrack = tidx[oid] track, oldTrack = tidx[oid]
if !oldTrack { if !oldTrack {
track = &nodeTrack{parent: parent, nchild: 0} // XXX track = &nodeInTree{parent: parent, nchild: 0} // XXX
/* /*
if i == l-1 { // leaf if i == l-1 { // leaf
track.holes = SetKey{} track.holes = SetKey{}
...@@ -432,13 +426,39 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) { ...@@ -432,13 +426,39 @@ func (tidx trackIndex) AddPath(path []zodb.Oid) {
} }
// Clone returns copy of the set.
// XXX place // XXX place
func (orig trackIndex) Clone() trackIndex { func (orig PPTreeSubSet) Clone() PPTreeSubSet {
klon := make(trackIndex, len(orig)) klon := make(PPTreeSubSet, len(orig))
for oid, t := range orig { for oid, t := range orig {
klon[oid] = &nodeTrack{parent: t.parent, nchild: t.nchild} klon[oid] = &nodeInTree{parent: t.parent, nchild: t.nchild}
} }
return klon return klon
} }
// equal returns whether a == b.
// XXX place
func (a PPTreeSubSet) equal(b PPTreeSubSet) bool {
if len(a) != len(b) {
return false
}
for oid, ta := range a {
tb, ok := b[oid]
if !ok {
return false
}
if !(ta.parent == tb.parent && ta.nchild == tb.nchild) {
return false
}
}
return true
}
func (t nodeInTree) String() string {
return fmt.Sprintf("{p%s c%d}", t.parent, t.nchild)
}
const debugPPSet = false const debugPPSet = false
...@@ -178,10 +178,10 @@ type ΔBtail struct { ...@@ -178,10 +178,10 @@ type ΔBtail struct {
// tracked nodes index: node -> parent + accessed holes under this node XXX -> holeIdx // tracked nodes index: node -> parent + accessed holes under this node XXX -> holeIdx
// we only allow single parent/root case and report "tree corrupt" otherwise. // we only allow single parent/root case and report "tree corrupt" otherwise.
// trackIdx describes @head state // trackIdx describes @head state
trackIdx trackIndex trackIdx PPTreeSubSet // XXX -> trackSet
// tree(s) subset that was requested to be tracked, but for which vδB was not yet rebuilt // tree(s) subset that was requested to be tracked, but for which vδB was not yet rebuilt
trackNew trackIndex trackNew PPTreeSubSet
// XXX root -> tracked holes // XXX root -> tracked holes
// XXX move -> ΔTtail ? // XXX move -> ΔTtail ?
...@@ -247,8 +247,8 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail { ...@@ -247,8 +247,8 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail {
return &ΔBtail{ return &ΔBtail{
δZtail: zodb.NewΔTail(at0), δZtail: zodb.NewΔTail(at0),
byRoot: map[zodb.Oid]*ΔTtail{}, byRoot: map[zodb.Oid]*ΔTtail{},
trackIdx: trackIndex{}, trackIdx: PPTreeSubSet{},
trackNew: trackIndex{}, trackNew: PPTreeSubSet{},
holeIdxByRoot: map[zodb.Oid]treeSetKey{}, holeIdxByRoot: map[zodb.Oid]treeSetKey{},
db: db, db: db,
} }
...@@ -383,7 +383,7 @@ func (δBtail *ΔBtail) rebuild() (err error) { ...@@ -383,7 +383,7 @@ func (δBtail *ΔBtail) rebuild() (err error) {
// XXX locking // XXX locking
trackNew := δBtail.trackNew trackNew := δBtail.trackNew
δBtail.trackNew = trackIndex{} δBtail.trackNew = PPTreeSubSet{}
if len(trackNew) == 0 { if len(trackNew) == 0 {
return return
...@@ -391,7 +391,7 @@ func (δBtail *ΔBtail) rebuild() (err error) { ...@@ -391,7 +391,7 @@ func (δBtail *ΔBtail) rebuild() (err error) {
// go backwards and merge vδT <- treediff(lo..hi/trackNew) // go backwards and merge vδT <- treediff(lo..hi/trackNew)
vδZ := δBtail.δZtail.Data() vδZ := δBtail.δZtail.Data()
vδtrack := []*δtrackIndex{} vδtrack := []*ΔPPTreeSubSet{}
for i := len(vδZ)-1; i>=0; i-- { for i := len(vδZ)-1; i>=0; i-- {
δZ := vδZ[i] δZ := vδZ[i]
...@@ -439,7 +439,7 @@ func (δBtail *ΔBtail) rebuild() (err error) { ...@@ -439,7 +439,7 @@ func (δBtail *ΔBtail) rebuild() (err error) {
tracef("-> root<%s> δkv*: %v δtrack*: %v\n", root, δT, δtrack) tracef("-> root<%s> δkv*: %v δtrack*: %v\n", root, δT, δtrack)
trackNew.ApplyΔ(δtrack) trackNew.ApplyΔ(δtrack)
vδtrack = append([]*δtrackIndex{δtrack}, vδtrack...) vδtrack = append([]*ΔPPTreeSubSet{δtrack}, vδtrack...)
if len(δT) == 0 { // an object might be resaved without change if len(δT) == 0 { // an object might be resaved without change
continue continue
...@@ -588,7 +588,7 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) { ...@@ -588,7 +588,7 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
// for example for e.g. t₀->t₁->b₂ if δZ/T={t₀ b₂} -> δZ/TC=δZ/T+{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} // δtopsByRoot = {} root -> {top changed nodes in that tree}
func δZConnectTracked(δZv []zodb.Oid, T trackIndex) (δZTC SetOid, δtopsByRoot map[zodb.Oid]SetOid) { func δZConnectTracked(δZv []zodb.Oid, T PPTreeSubSet) (δZTC SetOid, δtopsByRoot map[zodb.Oid]SetOid) {
δZ := SetOid{}; for _, δ := range δZv { δZ.Add(δ) } δZ := SetOid{}; for _, δ := range δZv { δZ.Add(δ) }
δZTC = SetOid{} δZTC = SetOid{}
δtopsByRoot = map[zodb.Oid]SetOid{} δtopsByRoot = map[zodb.Oid]SetOid{}
...@@ -816,14 +816,14 @@ func (rs rangeSplit) String() string { ...@@ -816,14 +816,14 @@ func (rs rangeSplit) String() string {
// //
// XXX holeIdx is updated XXX -> return similarly to δtrack // XXX holeIdx is updated XXX -> return similarly to δtrack
// XXX ^^^ -> but better kill holeIdx and do everything only via trackIdx // XXX ^^^ -> but better kill holeIdx and do everything only via trackIdx
func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, δtrack *δtrackIndex, err error) { func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, trackIdx PPTreeSubSet, holeIdx treeSetKey, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, δtrack *ΔPPTreeSubSet, err error) {
defer xerr.Contextf(&err, "treediff %s..%s %s", zconnOld.At(), zconnNew.At(), root) defer xerr.Contextf(&err, "treediff %s..%s %s", zconnOld.At(), zconnNew.At(), root)
tracef("\ntreediff %s δtops: %v δZTC: %v\n", root, δtops, δZTC) tracef("\ntreediff %s δtops: %v δZTC: %v\n", root, δtops, δZTC)
defer tracef("\n") defer tracef("\n")
δT = map[Key]ΔValue{} δT = map[Key]ΔValue{}
δtrackv := []*δtrackIndex{} δtrackv := []*ΔPPTreeSubSet{}
for top := range δtops { // XXX -> sorted? for top := range δtops { // XXX -> sorted?
a, err1 := zgetNode(ctx, zconnOld, top) a, err1 := zgetNode(ctx, zconnOld, top)
...@@ -863,7 +863,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -863,7 +863,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{Del: trackIndex{}, Add: trackIndex{}, δnchildNonLeafs: map[zodb.Oid]int{}} δtrack = &ΔPPTreeSubSet{Del: PPTreeSubSet{}, Add: PPTreeSubSet{}, δnchildNonLeafs: map[zodb.Oid]int{}}
for _, δ := range δtrackv { for _, δ := range δtrackv {
δtrack.Update(δ) δtrack.Update(δ)
} }
...@@ -880,9 +880,9 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -880,9 +880,9 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
// //
// a/b can be nil; a=nil means addition, b=nil means deletion. // a/b can be nil; a=nil means addition, b=nil means deletion.
// //
// δtrackIndex is trackIdx δ that needs to be applied to trackIdx to keep it // δtrackIdx is trackIdx δ that needs to be applied to trackIdx to keep it
// consistent with b (= a + δ). // consistent with b (= a + δ).
func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey) (δ map[Key]ΔValue, δtrackIdx *δtrackIndex, err error) { func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx PPTreeSubSet, holeIdx treeSetKey) (δ map[Key]ΔValue, δtrackIdx *ΔPPTreeSubSet, err error) {
if a==nil && b==nil { if a==nil && b==nil {
panic("BUG: both a & b == nil") panic("BUG: both a & b == nil")
} }
...@@ -919,10 +919,10 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, ho ...@@ -919,10 +919,10 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, ho
if isT { if isT {
return diffT(ctx, aT, bT, δZTC, trackIdx, holeIdx) return diffT(ctx, aT, bT, δZTC, trackIdx, holeIdx)
} else { } else {
var δtrack *δtrackIndex var δtrack *ΔPPTreeSubSet
δ, err := diffB(ctx, aB, bB) δ, err := diffB(ctx, aB, bB)
if δ != nil { if δ != nil {
δtrack = &δtrackIndex{} δtrack = &ΔPPTreeSubSet{}
} }
return δ, δtrack, err return δ, δtrack, err
} }
...@@ -932,7 +932,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, ho ...@@ -932,7 +932,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, ho
// //
// a, b point to top of subtrees @old and @new revisions. // a, b point to top of subtrees @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).
func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey) (δ map[Key]ΔValue, δtrack *δtrackIndex, err error) { func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx PPTreeSubSet, holeIdx treeSetKey) (δ map[Key]ΔValue, δtrack *ΔPPTreeSubSet, err error) {
tracef(" diffT %s %s\n", xidOf(A), xidOf(B)) tracef(" diffT %s %s\n", xidOf(A), xidOf(B))
defer xerr.Contextf(&err, "diffT %s %s", xidOf(A), xidOf(B)) defer xerr.Contextf(&err, "diffT %s %s", xidOf(A), xidOf(B))
...@@ -940,7 +940,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -940,7 +940,7 @@ 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{Del: trackIndex{}, Add: trackIndex{}, δnchildNonLeafs: map[zodb.Oid]int{}} δtrack = &ΔPPTreeSubSet{Del: PPTreeSubSet{}, Add: PPTreeSubSet{}, δnchildNonLeafs: map[zodb.Oid]int{}}
defer tracef(" -> δ: %v\n", δ) defer tracef(" -> δ: %v\n", δ)
// path prefix to A and B // path prefix to A and B
...@@ -978,7 +978,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h ...@@ -978,7 +978,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, h
// {} oid -> parent for all nodes in Bv: current and previously expanded - up till top B // {} oid -> parent for all nodes in Bv: current and previously expanded - up till top B
// XXX requires A.oid == B.oid // XXX requires A.oid == B.oid
BtrackIdx := trackIndex{} BtrackIdx := PPTreeSubSet{}
BtrackIdx.AddPath(trackIdx.Path(B.POid())) BtrackIdx.AddPath(trackIdx.Path(B.POid()))
// phase 1: expand A top->down driven by δZTC. // phase 1: expand A top->down driven by δZTC.
...@@ -1506,11 +1506,6 @@ func (rn nodeInRange) String() string { ...@@ -1506,11 +1506,6 @@ func (rn nodeInRange) String() string {
return fmt.Sprintf("%s[%s,%s)%s", done, slo, shi, vnode(rn.node)) return fmt.Sprintf("%s[%s,%s)%s", done, slo, shi, vnode(rn.node))
} }
func (track nodeTrack) String() string {
//return fmt.Sprintf("{p%s h%s}", track.parent, track.holes)
return fmt.Sprintf("{p%s c%d}", track.parent, track.nchild)
}
// push pushes element to node stack. // push pushes element to node stack.
func push(nodeStk *[]*nodeInRange, top *nodeInRange) { func push(nodeStk *[]*nodeInRange, top *nodeInRange) {
......
...@@ -313,8 +313,9 @@ func (rbs RBucketSet) holeIdx(tracked SetKey) SetKey { ...@@ -313,8 +313,9 @@ func (rbs RBucketSet) holeIdx(tracked SetKey) SetKey {
} }
// trackIdx returns what should be ΔBtree.trackIdx for specified tracked key set. // trackIdx returns what should be ΔBtree.trackIdx for specified tracked key set.
func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex { // XXX -> trackSet
trackIdx := trackIndex{} func (rbs RBucketSet) trackIdx(tracked SetKey) PPTreeSubSet {
trackIdx := PPTreeSubSet{}
for k := range tracked { for k := range tracked {
kb := rbs.Get(k) kb := rbs.Get(k)
// trackIdx explicitly records only regular buckets. // trackIdx explicitly records only regular buckets.
...@@ -323,7 +324,7 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex { ...@@ -323,7 +324,7 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex {
if kb.oid != zodb.InvalidOid { if kb.oid != zodb.InvalidOid {
track, already := trackIdx[kb.oid] track, already := trackIdx[kb.oid]
if !already { if !already {
track = &nodeTrack{parent: kb.parent.oid, nchild: 0} track = &nodeInTree{parent: kb.parent.oid, nchild: 0}
trackIdx[kb.oid] = track trackIdx[kb.oid] = track
newNode = true newNode = true
} }
...@@ -342,7 +343,7 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex { ...@@ -342,7 +343,7 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex {
pt, already := trackIdx[p.oid] pt, already := trackIdx[p.oid]
newParent := false newParent := false
if !already { if !already {
pt = &nodeTrack{parent: ppoid, nchild: 0} pt = &nodeInTree{parent: ppoid, nchild: 0}
trackIdx[p.oid] = pt trackIdx[p.oid] = pt
newParent = true newParent = true
} }
...@@ -754,7 +755,7 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod ...@@ -754,7 +755,7 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
// if !reflect.DeepEqual(trackIdx1, δbtail.trackIdx) { // if !reflect.DeepEqual(trackIdx1, δbtail.trackIdx) {
// badf("δbtail.trackIdx1 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx1) // badf("δbtail.trackIdx1 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx1)
// } // }
δbtail.assertTrack(t, "1", /*ø*/trackIndex{}, trackIdx1) δbtail.assertTrack(t, "1", /*ø*/PPTreeSubSet{}, trackIdx1)
// δB <- δZ // δB <- δZ
...@@ -777,7 +778,7 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod ...@@ -777,7 +778,7 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
// if !reflect.DeepEqual(trackIdx2, δbtail.trackIdx) { // if !reflect.DeepEqual(trackIdx2, δbtail.trackIdx) {
// badf("δbtail.trackIdx2 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx2) // badf("δbtail.trackIdx2 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx2)
// } // }
δbtail.assertTrack(t, "2", trackIdx2, /*ø*/trackIndex{}) δbtail.assertTrack(t, "2", trackIdx2, /*ø*/PPTreeSubSet{})
// assert δB.ByRoot == {treeRoot -> ...} if δTok != ø // assert δB.ByRoot == {treeRoot -> ...} if δTok != ø
...@@ -837,30 +838,9 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod ...@@ -837,30 +838,9 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
} }
} }
// equal returns whether a == b.
// XXX place
func (a trackIndex) equal(b trackIndex) bool {
if len(a) != len(b) {
return false
}
for oid, ta := range a {
tb, ok := b[oid]
if !ok {
return false
}
if !(ta.parent == tb.parent && ta.nchild == tb.nchild) {
return false
}
}
return true
}
// assertTrack verifies that trackIdx == trackIdxOK. // assertTrack verifies that trackIdx == trackIdxOK.
// XXX place // XXX place
func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK trackIndex) { func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK PPTreeSubSet) {
t.Helper() t.Helper()
// eq := reflect.DeepEqual(trackIdx, trackIdxOK) // slower // eq := reflect.DeepEqual(trackIdx, trackIdxOK) // slower
eq := trackIdx.equal(trackIdxOK) eq := trackIdx.equal(trackIdxOK)
...@@ -871,7 +851,7 @@ func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK trackIndex) { ...@@ -871,7 +851,7 @@ func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK trackIndex) {
// assertTrack verifies state of .trackIdx and .trackNew. // assertTrack verifies state of .trackIdx and .trackNew.
// XXX place // XXX place
func (δbtail *ΔBtail) assertTrack(t *testing.T, subj string, trackIdxOK, trackNewOK trackIndex) { func (δbtail *ΔBtail) assertTrack(t *testing.T, subj string, trackIdxOK, trackNewOK PPTreeSubSet) {
t.Helper() t.Helper()
assertTrack(t, subj + ": trackIdx", δbtail.trackIdx, trackIdxOK) assertTrack(t, subj + ": trackIdx", δbtail.trackIdx, trackIdxOK)
assertTrack(t, subj + ": trackNew", δbtail.trackNew, trackNewOK) assertTrack(t, subj + ": trackNew", δbtail.trackNew, trackNewOK)
...@@ -905,7 +885,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -905,7 +885,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
kadj21 := KAdj(t2,t1, allTestKeys(t0,t1,t2)) kadj21 := KAdj(t2,t1, allTestKeys(t0,t1,t2))
kadj12 := KAdj(t1,t2, allTestKeys(t0,t1,t2)) kadj12 := KAdj(t1,t2, allTestKeys(t0,t1,t2))
ø := trackIndex{} ø := PPTreeSubSet{}
// verify t0 -> t1 Track(keys1) Rebuild -> t2 Track(keys2) Rebuild // verify t0 -> t1 Track(keys1) Rebuild -> t2 Track(keys2) Rebuild
// for all combinations of keys1 and keys2 // for all combinations of keys1 and keys2
...@@ -995,10 +975,10 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -995,10 +975,10 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
} }
// xverifyΔBTail_rebuild_U verifies ΔBTree state after Update(ti->tj). // xverifyΔBTail_rebuild_U verifies ΔBTree state after Update(ti->tj).
func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, ti, tj *tTreeCommit, xat map[zodb.Tid]string, trackIdx trackIndex) { func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, ti, tj *tTreeCommit, xat map[zodb.Tid]string, trackIdx PPTreeSubSet) {
t.Helper() t.Helper()
X := exc.Raiseif X := exc.Raiseif
ø := trackIndex{} ø := PPTreeSubSet{}
// Update ati -> atj // Update ati -> atj
δB, err := δbtail.Update(tj.δZ); X(err) δB, err := δbtail.Update(tj.δZ); X(err)
...@@ -1008,10 +988,10 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, ti, tj *tTreeCommi ...@@ -1008,10 +988,10 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, ti, tj *tTreeCommi
} }
// xverifyΔBTail_rebuild_TR verifies ΔBTree state after Track(keys) + rebuild. // xverifyΔBTail_rebuild_TR verifies ΔBTree state after Track(keys) + rebuild.
func xverifyΔBTail_rebuild_TR(t *testing.T, db *zodb.DB, δbtail *ΔBtail, tj *tTreeCommit, treeRoot zodb.Oid, xat map[zodb.Tid]string, keys SetKey, trackIdx trackIndex, trackNew, trackIdxAfterRebuild trackIndex,vδTok ...map[Key]Δstring) { func xverifyΔBTail_rebuild_TR(t *testing.T, db *zodb.DB, δbtail *ΔBtail, tj *tTreeCommit, treeRoot zodb.Oid, xat map[zodb.Tid]string, keys SetKey, trackIdx PPTreeSubSet, trackNew, trackIdxAfterRebuild PPTreeSubSet,vδTok ...map[Key]Δstring) {
t.Helper() t.Helper()
X := exc.Raiseif X := exc.Raiseif
ø := trackIndex{} ø := PPTreeSubSet{}
// Track(keys) // Track(keys)
txn, ctx := transaction.New(context.Background()) txn, ctx := transaction.New(context.Background())
......
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