Commit a1f0152e authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent b862634c
......@@ -253,7 +253,10 @@ func (tg *AllStructsSrv) AllStructs(kv1, kv2 map[Key]string, maxdepth, maxsplit,
// XGetTree loads Tree from zurl@at->obj<root>.
// Tree values must be ZBlk whose data is returned instead of references to ZBlk objects.
func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) map[Key]string {
// The tree is returned structured by buckets as
// {} k -> {k->v}
// where key k points to {k->v} that represents k's bucket.
func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) map[Key]map[Key]string {
defer exc.Contextf("%s: @%s: get tree %s", db.Storage().URL(), at, root)
X := exc.Raiseif
......@@ -273,11 +276,12 @@ func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) map[Key]string {
defer ztree.PDeactivate()
zbucket := ztree.FirstBucket()
kv := make(map[Key]string)
xkv := make(map[Key]map[Key]string)
for zbucket != nil {
err = zbucket.PActivate(ctx); X(err)
defer zbucket.PDeactivate()
bkv := make(map[Key]string)
for _, __ := range zbucket.Entryv() {
k := __.Key()
xv := __.Value()
......@@ -287,13 +291,17 @@ func XGetTree(db *zodb.DB, at zodb.Tid, root zodb.Oid) map[Key]string {
}
data, _, err := zv.loadBlkData(ctx); X(err)
kv[k] = string(data)
bkv[k] = string(data)
}
for k := range bkv {
xkv[k] = bkv
}
zbucket = zbucket.Next()
}
return kv
return xkv
}
// XGetKV translates {k -> <oid>} to {k -> ZBlk(oid).data} according to db@at snapshot.
......@@ -324,15 +332,15 @@ func XGetKV(db *zodb.DB, at zodb.Tid, kvOid map[Key]Value) map[Key]string {
// xverifyΔBTail verifies how ΔBTail handles ZODB update for a tree with changes in between at1->at2.
//
// it is known that @at1 and @at2 the tree has kv1 and kv2 values correspondingly.
// it is known that @at1 and @at2 the tree has xkv1 and xkv2 values correspondingly.
// it is known that for at1->at2 ZODB-level change is δZ.
func xverifyΔBTail(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, at1, at2 zodb.Tid, kv1, kv2 map[Key]string, δZ *zodb.EventCommit) {
d12 := kvdiff(kv1, kv2)
func xverifyΔBTail(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, at1, at2 zodb.Tid, xkv1, xkv2 map[Key]map[Key]string, δZ *zodb.EventCommit) {
d12 := kvdiff(xkvFlatten(xkv1), xkvFlatten(xkv2))
// verify transition at1->at2 for all initial states of tracked {keys} from kv1 + kv2 + ∞
allKeys := SetKey{}; allKeys.Add(kInf) // inf, simulating ZBigFile.Size() query
for k := range kv1 { allKeys.Add(k) }
for k := range kv2 { allKeys.Add(k) }
for k := range xkv1 { allKeys.Add(k) }
for k := range xkv2 { allKeys.Add(k) }
allKeyv := allKeys.Elements()
sort.Slice(allKeyv, func(i, j int) bool {
return allKeyv[i] < allKeyv[j]
......@@ -509,19 +517,19 @@ func testΔBTail(t *testing.T, testq chan string) {
return δZ
}
at1 := tg.head
kv1 := XGetTree(db, at1, tg.treeRoot)
at1 := tg.head
xkv1 := XGetTree(db, at1, tg.treeRoot)
tree1 := "ø" // initial
for tree2 := range testq {
δZ := XCommitTree(tree2)
at2 := δZ.Tid
kv2 := XGetTree(db, at2, tg.treeRoot)
at2 := δZ.Tid
xkv2 := XGetTree(db, at2, tg.treeRoot)
subj := fmt.Sprintf("%s -> %s", tree1, tree2)
xverifyΔBTail(t, subj, db, tg.treeRoot, at1,at2, kv1,kv2, δZ)
xverifyΔBTail(t, subj, db, tg.treeRoot, at1,at2, xkv1,xkv2, δZ)
at1 = at2
kv1 = kv2
at1 = at2
xkv1 = xkv2
tree1 = tree2
}
}
......@@ -531,18 +539,19 @@ func TestΔBTail(t *testing.T) {
// test known cases going through tree1 -> tree2 -> ...
testv := []string {
"T/B:",
"T/B1:a", // +1
"T/B1:a,2:b", // +2
"T/B2:b", // -1
"T/B2:c", // 2: b->c
"T2/B1:a-B2:c", // +1 in new bucket
"T/B1:a", // +1
"T/B1:a,2:b", // +2
"T/B2:b", // -1
"T/B2:c", // 2: b->c
"T2/B1:a-B2:c", // +1 in new bucket (to the left)
"T2,3/B1:a-B2:c-B3:c", // +3 in new bucket (to the right)
// bucket split; +3 in new bucket
"T/B1:a,2:b",
"T2/B1:a-B2:b,3:c",
// bucket split; +3 in new bucket; +4 +5 in another new bucket
// which remain not tracked (TODO verify)
// which remain not tracked (XXX unless TrackMaxKey TODO verify)
"T/B1:a,2:b",
"T2,4/B1:a-B2:b,3:c-B4:d,5:e",
......@@ -791,3 +800,14 @@ func TestKVTxt(t *testing.T) {
t.Fatalf("error:\ngot: %q\nwant: %q", got, want)
}
}
// xkvFlatten converts xkv with bucket structure into regular dict.
func xkvFlatten(xkv map[Key]map[Key]string) map[Key]string {
kv := make(map[Key]string)
for _, bkv := range xkv {
for k,v := range bkv {
kv[k] = v
}
}
return kv
}
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