Commit 0480d21d authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 05c78d30
...@@ -174,8 +174,8 @@ type ΔBtail struct { ...@@ -174,8 +174,8 @@ 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
// XXX -> parentIdx map[zodb.Oid]zodb.Oid ? //trackIdx map[zodb.Oid]nodeTrack
trackIdx map[zodb.Oid]nodeTrack trackIdx trackIndex
// XXX tracked holes // XXX tracked holes
holeIdx treeSetKey holeIdx treeSetKey
...@@ -184,17 +184,25 @@ type ΔBtail struct { ...@@ -184,17 +184,25 @@ type ΔBtail struct {
// trackNew SetOid // trackNew SetOid
} }
// XXX place
type trackIndex map[zodb.Oid]*nodeTrack
// XXX place // XXX place
// nodeTrack represents tracking information about a node. // nodeTrack represents tracking information about a node.
// XXX kill (parentIdx is just {} oid -> oid) //// XXX kill (parentIdx is just {} oid -> oid)
type nodeTrack 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
/* /*
holes SetKey // missing keys tracked under this node; nil for !leaf holes SetKey // missing keys tracked under this node; nil for !leaf
// XXX move holes into separate ΔBtail..holeIdx // XXX move holes into separate ΔBtail..holeIdx
*/ */
} }
func (tidx trackIndex) DelLeaf(oid zodb.Oid) {
panic("TODO")
}
// treeSetKey represents ordered set of keys. // treeSetKey represents ordered set of keys.
// it can be point-queried and range-accessed. // it can be point-queried and range-accessed.
// TODO -> btree // TODO -> btree
...@@ -259,7 +267,7 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail { ...@@ -259,7 +267,7 @@ 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: map[zodb.Oid]nodeTrack{}, trackIdx: trackIndex{},
holeIdx: treeSetKey{SetKey{}}, holeIdx: treeSetKey{SetKey{}},
db: db, db: db,
} }
...@@ -308,19 +316,17 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { // ...@@ -308,19 +316,17 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { //
tracef("Track [%v] %s\n", key, strings.Join(pathv, " -> ")) tracef("Track [%v] %s\n", key, strings.Join(pathv, " -> "))
parent := zodb.InvalidOid parent := zodb.InvalidOid
var track nodeTrack var ptrack *nodeTrack = nil
var track *nodeTrack // XXX kill here
var oldTrack bool var oldTrack bool
for _, node := range path { for _, node := range path {
oid := node.POid() oid := node.POid()
// XXX skip InvalidOid ?
// InvalidOid means embedded bucket - e.g. T/B1:a with bucket not having its own oid. // InvalidOid means embedded bucket - e.g. T/B1:a with bucket not having its own oid.
//if oid == zodb.InvalidOid {
// // XXX verify node is leaf; else panic
// continue
//}
track, oldTrack = δBtail.trackIdx[oid] track, oldTrack = δBtail.trackIdx[oid]
if !oldTrack { if !oldTrack {
track = nodeTrack{parent: parent} track = &nodeTrack{parent: parent, nchild: 0} // XXX
/* /*
if i == l-1 { // leaf if i == l-1 { // leaf
track.holes = SetKey{} track.holes = SetKey{}
...@@ -334,7 +340,13 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { // ...@@ -334,7 +340,13 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { //
panicf("node %s is reachable from multiple parents: %s %s", panicf("node %s is reachable from multiple parents: %s %s",
oid, track.parent, parent) oid, track.parent, parent)
} }
if ptrack != nil {
ptrack.nchild++
}
parent = oid parent = oid
ptrack = track
} }
// track is track of path[-1] (i.e. leaf) // track is track of path[-1] (i.e. leaf)
...@@ -489,7 +501,7 @@ func (δBtail *ΔBtail) δZConnectTracked(δZv *zodb.EventCommit) (δZTC SetOid, ...@@ -489,7 +501,7 @@ func (δBtail *ΔBtail) δZConnectTracked(δZv *zodb.EventCommit) (δZTC SetOid,
// XXX place // XXX place
// nodeInRange represents a Node coming under [lo, hi_] key range in its tree. // nodeInRange represents a Node coming under [lo, hi_] key range in its tree.
type nodeInRange struct { type nodeInRange struct {
// XXX +parent? parent *nodeInRange
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞
node Node node Node
done bool // whether this node was already taken into account while computing diff done bool // whether this node was already taken into account while computing diff
...@@ -641,13 +653,14 @@ func (rs rangeSplit) String() string { ...@@ -641,13 +653,14 @@ func (rs rangeSplit) String() string {
// δtops is set of top nodes for changed subtrees. // δtops is set of top nodes for changed subtrees.
// δZTC is connected(δZ/T) - connected closure for subset of δZ(old..new) that // δZTC is connected(δZ/T) - connected closure for subset of δZ(old..new) that
// touches tracked nodes of T. // touches tracked nodes of T.
func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack, holeIdx treeSetKey, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, err error) { func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey, zconnOld, zconnNew *zodb.Connection) (δT map[Key]ΔValue, 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{}
trackDel := SetOid{}
for top := range δtops { // XXX -> sorted? for top := range δtops { // XXX -> sorted?
a, err1 := zgetNode(ctx, zconnOld, top) a, err1 := zgetNode(ctx, zconnOld, top)
...@@ -683,7 +696,38 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -683,7 +696,38 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
} }
} }
// XXX adjust trackIdx // adjust trackIdx
for oid := range trackDel {
_, present := trackIdx[oid]
if !present {
continue
}
trackIdx.DelLeaf(oid)
}
/*
for leaf := range trackAdd {
node := leaf
for node != nil {
parent := node.parent
oid := node.node.POid()
poid := zodb.InvalidOid
if parent != nil {
poid = parent.node.POid()
}
track, already := trackIdx[oid]
if !already {
track = nodeTrack{parent: poid}
trackIdx[oid] = track
}
if track.parent != poid {
// XXX -> error (e.g. data corruption in ZODB)
panicf("node %s has multiple parents: %s %s", oid, poid, track.parent)
}
// XXX incref trackIdx[track.parent]
node = parent
}
}
*/
return δT, nil return δT, nil
} }
...@@ -696,7 +740,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t ...@@ -696,7 +740,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
// δ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).
// //
// 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.
func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack, holeIdx treeSetKey) (δ map[Key]ΔValue, err error) { func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey) (δ map[Key]ΔValue, err error) {
if a==nil && b==nil { if a==nil && b==nil {
panic("BUG: both a & b == nil") panic("BUG: both a & b == nil")
} }
...@@ -744,7 +788,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx map[zodb.Oid]n ...@@ -744,7 +788,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx map[zodb.Oid]n
// //
// XXX trackIdx -> just pass δBtail? // XXX trackIdx -> just pass δBtail?
// XXX ----//---- holeIdx // XXX ----//---- holeIdx
func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]nodeTrack, holeIdx treeSetKey) (δ map[Key]ΔValue, err error) { func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx trackIndex, holeIdx treeSetKey) (δ map[Key]ΔValue, 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))
...@@ -782,8 +826,12 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -782,8 +826,12 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// {} 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 // XXX
// XXX requires A.oid == B.oid // XXX requires A.oid == B.oid
// 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}}
trackDel := SetOid{} // leaf nodes to be removed from trackIdx after treediff
// trackAdd := SetNode{} // leaf nodes to be added to trackIdx after treediff
// 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 δ-
// a node ac does not contribute to δ- and can be skipped, if: // a node ac does not contribute to δ- and can be skipped, if:
...@@ -805,6 +853,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -805,6 +853,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// a is bucket -> δ- // a is bucket -> δ-
δA, err := diffB(ctx, a, nil); /*X*/if err != nil { return nil, err } δA, err := diffB(ctx, a, nil); /*X*/if err != nil { return nil, err }
err = δMerge(δ, δA); /*X*/if err != nil { return nil, err } err = δMerge(δ, δA); /*X*/if err != nil { return nil, err }
trackDel.Add(a.POid())
// Bkqueue <- δA // Bkqueue <- δA
for k := range δA { for k := range δA {
...@@ -927,6 +976,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -927,6 +976,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δB // δ <- δB
err = δMerge(δ, δB); /*X*/if err != nil { return nil, err } err = δMerge(δ, δB); /*X*/if err != nil { return nil, err }
// trackAdd.Add(b)
// Akqueue <- δB // Akqueue <- δB
for k_ := range δB { for k_ := range δB {
...@@ -956,6 +1006,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid] ...@@ -956,6 +1006,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δA // δ <- δA
err = δMerge(δ, δA); /*X*/if err != nil { return nil, err } err = δMerge(δ, δA); /*X*/if err != nil { return nil, err }
trackDel.Add(a.node.POid())
// Bkqueue <- δA // Bkqueue <- δA
for k_ := range δA { for k_ := range δA {
...@@ -1286,7 +1337,7 @@ func (rn nodeInRange) String() string { ...@@ -1286,7 +1337,7 @@ func (rn nodeInRange) String() string {
func (track nodeTrack) String() string { func (track nodeTrack) String() string {
//return fmt.Sprintf("{p%s h%s}", track.parent, track.holes) //return fmt.Sprintf("{p%s h%s}", track.parent, track.holes)
return fmt.Sprintf("{p%s}", track.parent) return fmt.Sprintf("{p%s c%d}", track.parent, track.nchild)
} }
......
...@@ -67,6 +67,7 @@ import ( ...@@ -67,6 +67,7 @@ import (
) )
const kInf Key = 10000 // inf key (TeX hack) const kInf Key = 10000 // inf key (TeX hack)
//const kInf Key = KeyMax
// XXX move infrastructure -> δbtail_treegen_test.go ? // XXX move infrastructure -> δbtail_treegen_test.go ?
...@@ -334,17 +335,18 @@ func (rbs RBucketSet) holeIdx(tracked SetKey) SetKey { ...@@ -334,17 +335,18 @@ 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) map[zodb.Oid]nodeTrack { func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex {
trackIdx := map[zodb.Oid]nodeTrack{} trackIdx := trackIndex{}
for k := range tracked { for k := range tracked {
kb := rbs.Get(k) kb := rbs.Get(k)
// trackIdx records regular buckets or non-empty embedded bucket // trackIdx records regular buckets or non-empty embedded bucket
// (empty embedded bucket means there is just empty tree node // ( empty embedded bucket means there is just empty tree node
// and only that is recorded in trackIdx) // and only that empty tree node is recorded in trackIdx )
if kb.oid != zodb.InvalidOid || len(kb.kv) != 0 { trackKB := (kb.oid != zodb.InvalidOid || len(kb.kv) != 0)
if trackKB {
track, already := trackIdx[kb.oid] track, already := trackIdx[kb.oid]
if !already { if !already {
track = nodeTrack{parent: kb.parent.oid} track = &nodeTrack{parent: kb.parent.oid, nchild: 0}
trackIdx[kb.oid] = track trackIdx[kb.oid] = track
} }
if track.parent != kb.parent.oid { if track.parent != kb.parent.oid {
...@@ -361,13 +363,16 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) map[zodb.Oid]nodeTrack { ...@@ -361,13 +363,16 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) map[zodb.Oid]nodeTrack {
pt, already := trackIdx[p.oid] pt, already := trackIdx[p.oid]
if !already { if !already {
pt = nodeTrack{parent: ppoid} pt = &nodeTrack{parent: ppoid, nchild: 0}
trackIdx[p.oid] = pt trackIdx[p.oid] = pt
} }
if pt.parent != ppoid { if pt.parent != ppoid {
panicf("BUG: %s: T%s -> multiple parents: %s %s", rbs.coverage(), p.oid, pt.parent, ppoid) panicf("BUG: %s: T%s -> multiple parents: %s %s", rbs.coverage(), p.oid, pt.parent, ppoid)
} }
if trackKB {
pt.nchild++
}
p = p.parent p = p.parent
} }
} }
...@@ -616,7 +621,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, ...@@ -616,7 +621,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
emsg += strings.Join(badv, "\n") emsg += strings.Join(badv, "\n")
emsg += "\n" emsg += "\n"
t.Error(emsg) t.Fatal(emsg)
} }
}() }()
...@@ -678,7 +683,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, ...@@ -678,7 +683,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
// trackIdx1 = xkv1[tracked1] // trackIdx1 = xkv1[tracked1]
trackIdx1 := xkv1.trackIdx(initialTrackedKeys) trackIdx1 := xkv1.trackIdx(initialTrackedKeys)
if !reflect.DeepEqual(trackIdx1, δbtail.trackIdx) { if !reflect.DeepEqual(trackIdx1, δbtail.trackIdx) {
badf("δbtail.trackIdx1 wrong ; trackIdx=%v trackIdxOK=%v", δbtail.trackIdx, trackIdx1) badf("δbtail.trackIdx1 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx1)
} }
...@@ -696,14 +701,12 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, ...@@ -696,14 +701,12 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
badf("δbtail.holeIdx2 wrong ; holeIdx=%v holeIdxOK=%v", δbtail.holeIdx, holes2) badf("δbtail.holeIdx2 wrong ; holeIdx=%v holeIdxOK=%v", δbtail.holeIdx, holes2)
} }
// verify δbtail.traciIdx against @at2 // verify δbtail.trackIdx against @at2
// trackIdx2 = xkv2[tracked2] ( = xkv2[kadj[tracked1]] // trackIdx2 = xkv2[tracked2] ( = xkv2[kadj[tracked1]]
/* XXX reenable
trackIdx2 := xkv2.trackIdx(kadjTracked) trackIdx2 := xkv2.trackIdx(kadjTracked)
if !reflect.DeepEqual(trackIdx2, δbtail.trackIdx) { if !reflect.DeepEqual(trackIdx2, δbtail.trackIdx) {
badf("δbtail.trackIdx2 wrong ; trackIdx=%v trackIdxOK=%v", δbtail.trackIdx, trackIdx2) badf("δbtail.trackIdx2 wrong:\n\thave: %v\n\twant: %v", δbtail.trackIdx, trackIdx2)
} }
*/
// assert δB.ByRoot == {treeRoot -> ...} if δTok != ø // assert δB.ByRoot == {treeRoot -> ...} if δ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