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

.

parent 05c78d30
......@@ -174,8 +174,8 @@ type ΔBtail struct {
// tracked nodes index: node -> parent + accessed holes under this node XXX -> holeIdx
// we only allow single parent/root case and report "tree corrupt" otherwise.
// 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
holeIdx treeSetKey
......@@ -184,17 +184,25 @@ type ΔBtail struct {
// trackNew SetOid
}
// XXX place
type trackIndex map[zodb.Oid]*nodeTrack
// XXX place
// nodeTrack represents tracking information about a node.
// XXX kill (parentIdx is just {} oid -> oid)
//// XXX kill (parentIdx is just {} oid -> oid)
type nodeTrack struct {
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
// XXX move holes into separate ΔBtail..holeIdx
*/
}
func (tidx trackIndex) DelLeaf(oid zodb.Oid) {
panic("TODO")
}
// treeSetKey represents ordered set of keys.
// it can be point-queried and range-accessed.
// TODO -> btree
......@@ -259,7 +267,7 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail {
return &ΔBtail{
δZtail: zodb.NewΔTail(at0),
byRoot: map[zodb.Oid]*ΔTtail{},
trackIdx: map[zodb.Oid]nodeTrack{},
trackIdx: trackIndex{},
holeIdx: treeSetKey{SetKey{}},
db: db,
}
......@@ -308,19 +316,17 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { //
tracef("Track [%v] %s\n", key, strings.Join(pathv, " -> "))
parent := zodb.InvalidOid
var track nodeTrack
var ptrack *nodeTrack = nil
var track *nodeTrack // XXX kill here
var oldTrack bool
for _, node := range path {
oid := node.POid()
// XXX skip InvalidOid ?
// 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]
if !oldTrack {
track = nodeTrack{parent: parent}
track = &nodeTrack{parent: parent, nchild: 0} // XXX
/*
if i == l-1 { // leaf
track.holes = SetKey{}
......@@ -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",
oid, track.parent, parent)
}
if ptrack != nil {
ptrack.nchild++
}
parent = oid
ptrack = track
}
// track is track of path[-1] (i.e. leaf)
......@@ -489,7 +501,7 @@ func (δBtail *ΔBtail) δZConnectTracked(δZv *zodb.EventCommit) (δZTC SetOid,
// XXX place
// nodeInRange represents a Node coming under [lo, hi_] key range in its tree.
type nodeInRange struct {
// XXX +parent?
parent *nodeInRange
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞
node Node
done bool // whether this node was already taken into account while computing diff
......@@ -641,13 +653,14 @@ func (rs rangeSplit) String() string {
// δtops is set of top nodes for changed subtrees.
// δZTC is connected(δZ/T) - connected closure for subset of δZ(old..new) that
// 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)
tracef("\ntreediff %s δtops: %v δZTC: %v\n", root, δtops, δZTC)
defer tracef("\n")
δT = map[Key]ΔValue{}
trackDel := SetOid{}
for top := range δtops { // XXX -> sorted?
a, err1 := zgetNode(ctx, zconnOld, top)
......@@ -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
}
......@@ -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).
//
// 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 {
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
//
// XXX trackIdx -> just pass δBtail?
// 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))
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]
// {} oid -> parent for all nodes in Bv: current and previously expanded - up till top B
// XXX
// XXX requires A.oid == B.oid
// XXX -> trackIndex
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.
// by default a node contributes to δ-
// 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]
// a is bucket -> δ-
δA, err := diffB(ctx, a, nil); /*X*/if err != nil { return nil, err }
err = δMerge(δ, δA); /*X*/if err != nil { return nil, err }
trackDel.Add(a.POid())
// Bkqueue <- δA
for k := range δA {
......@@ -927,6 +976,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δB
err = δMerge(δ, δB); /*X*/if err != nil { return nil, err }
// trackAdd.Add(b)
// Akqueue <- δB
for k_ := range δB {
......@@ -956,6 +1006,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δA
err = δMerge(δ, δA); /*X*/if err != nil { return nil, err }
trackDel.Add(a.node.POid())
// Bkqueue <- δA
for k_ := range δA {
......@@ -1286,7 +1337,7 @@ func (rn nodeInRange) String() string {
func (track nodeTrack) String() string {
//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 (
)
const kInf Key = 10000 // inf key (TeX hack)
//const kInf Key = KeyMax
// XXX move infrastructure -> δbtail_treegen_test.go ?
......@@ -334,17 +335,18 @@ func (rbs RBucketSet) holeIdx(tracked SetKey) SetKey {
}
// trackIdx returns what should be ΔBtree.trackIdx for specified tracked key set.
func (rbs RBucketSet) trackIdx(tracked SetKey) map[zodb.Oid]nodeTrack {
trackIdx := map[zodb.Oid]nodeTrack{}
func (rbs RBucketSet) trackIdx(tracked SetKey) trackIndex {
trackIdx := trackIndex{}
for k := range tracked {
kb := rbs.Get(k)
// trackIdx records regular buckets or non-empty embedded bucket
// (empty embedded bucket means there is just empty tree node
// and only that is recorded in trackIdx)
if kb.oid != zodb.InvalidOid || len(kb.kv) != 0 {
// ( empty embedded bucket means there is just empty tree node
// and only that empty tree node is recorded in trackIdx )
trackKB := (kb.oid != zodb.InvalidOid || len(kb.kv) != 0)
if trackKB {
track, already := trackIdx[kb.oid]
if !already {
track = nodeTrack{parent: kb.parent.oid}
track = &nodeTrack{parent: kb.parent.oid, nchild: 0}
trackIdx[kb.oid] = track
}
if track.parent != kb.parent.oid {
......@@ -361,13 +363,16 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) map[zodb.Oid]nodeTrack {
pt, already := trackIdx[p.oid]
if !already {
pt = nodeTrack{parent: ppoid}
pt = &nodeTrack{parent: ppoid, nchild: 0}
trackIdx[p.oid] = pt
}
if 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
}
}
......@@ -616,7 +621,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
emsg += strings.Join(badv, "\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,
// trackIdx1 = xkv1[tracked1]
trackIdx1 := xkv1.trackIdx(initialTrackedKeys)
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,
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]]
/* XXX reenable
trackIdx2 := xkv2.trackIdx(kadjTracked)
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 != ø
......
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