Commit e9ecca3a authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 7b4ad4d3
...@@ -21,28 +21,6 @@ package main ...@@ -21,28 +21,6 @@ package main
// tests for δbtail.go // tests for δbtail.go
// XXX doc (2 ways of testing: explicit + allstructs), treegen py helper // XXX doc (2 ways of testing: explicit + allstructs), treegen py helper
// Adjacency matrix
//
// A, B - topologies ex T/B1 T2/B1-B3
// Av, Bv - topologies with values ex T/B1:a T2/B1:b-B3:c
//
// δ(Av, Bv) - full diff {k -> v} for changed keys; DEL = k -> ø
// ex δ(T/B1:a, T2/B1:b-B3:c) = {1:b 3:c} XXX include "was" value too?
//
// Δ(T, Av, Bv) - subset of δ(Av, Bv) corresponding to initial tracking set T
// ex Δ({1}, T/B1:a, T2/B1:b-B3:c) = {1:b} (no 3:c)
//
// kadj(A,B) {} k -> {k'}: - adjacency matrix
// ∃v1,v2: k'∈ Δ({k}, Av1, Bv2)
//
// ex kadj(T/B1, T2/B1-B3) = {1:{1} 3:{1,3} ∞:{1,3}} k ∈ A+B+{∞}
// + {0:{1} 2:{1,3} + ... all possible keys}
//
// Δ(T, Av, Bv) = δ(Av, Bv)/kadj(A,B)[T]
//
// i.e. = δ(Av, Bv) for k: k ∈ U kadj(A,B)[·]
// ·∈T
import ( import (
"bufio" "bufio"
"context" "context"
...@@ -544,12 +522,51 @@ func xzgetBlkDataAt(db *zodb.DB, zblkOid zodb.Oid, at zodb.Tid) string { ...@@ -544,12 +522,51 @@ func xzgetBlkDataAt(db *zodb.DB, zblkOid zodb.Oid, at zodb.Tid) string {
return xzgetBlkData(ctx, zconn, zblkOid) return xzgetBlkData(ctx, zconn, zblkOid)
} }
// KAdjMatrix is adjacency matrix that describes how set of tracked keys
// changes when tree topology is updated from A to B.
//
// Adjacency matrix
//
// A, B - topologies ex T/B1 T2/B1-B3
// Av, Bv - topologies with values ex T/B1:a T2/B1:b-B3:c
//
// δ(Av, Bv) - full diff {k -> v} for changed keys; DEL = k -> ø
// ex δ(T/B1:a, T2/B1:b-B3:c) = {1:b 3:c} XXX include "was" value too?
//
// Δ(T, Av, Bv) - subset of δ(Av, Bv) corresponding to initial tracking set T
// ex Δ({1}, T/B1:a, T2/B1:b-B3:c) = {1:b} (no 3:c)
//
// kadj(A,B) {} k -> {k'}: - adjacency matrix
// ∃v1,v2: k'∈ Δ({k}, Av1, Bv2)
//
// ex kadj(T/B1, T2/B1-B3) = {1:{1} 3:{1,3} ∞:{1,3}} k ∈ A+B+{∞}
// + {0:{1} 2:{1,3} + ... all possible keys}
//
// Δ(T, Av, Bv) = δ(Av, Bv)/kadj(A,B)[T]
//
// i.e. = δ(Av, Bv) for k: k ∈ U kadj(A,B)[·]
// ·∈T
type KAdjMatrix map[Key]SetKey
// Map returns kadj·keys .
func (kadj KAdjMatrix) Map(keys SetKey) SetKey {
res := SetKey{}
for k := range keys {
to, ok := kadj[k]
if !ok {
panicf("%d ∉ kadj\n\nkadj: %v", k, kadj)
}
res.Update(to)
}
return res
}
// KAdj computes adjacency matrix for t1 -> t2 transition. // KAdj computes adjacency matrix for t1 -> t2 transition.
// KAdj itself is verified by testΔBTail on entries with .kadjOK set. // KAdj itself is verified by testΔBTail on entries with .kadjOK set.
func KAdj(t1, t2 *tTreeCommit) (kadj map[Key]SetKey) { func KAdj(t1, t2 *tTreeCommit) (kadj KAdjMatrix) {
// kadj = {} k -> adjacent keys. // kadj = {} k -> adjacent keys.
// if k is tracked -> changes to adjacents must be in Update(t1->t2). // if k is tracked -> changes to adjacents must be in Update(t1->t2).
kadj = map[Key]SetKey{} kadj = KAdjMatrix{}
for k := range allTestKeys(t1, t2) { for k := range allTestKeys(t1, t2) {
adj1 := SetKey{} adj1 := SetKey{}
adj2 := SetKey{} adj2 := SetKey{}
...@@ -798,7 +815,7 @@ func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK trackIndex) { ...@@ -798,7 +815,7 @@ func assertTrack(t *testing.T, subj string, trackIdx, trackIdxOK trackIndex) {
} }
} }
// assertTrack verifies state of .trackIdx and .newTrackIdx. // 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 trackIndex) {
assertTrack(t, subj + ": trackIdx", δbtail.trackIdx, trackIdxOK) assertTrack(t, subj + ": trackIdx", δbtail.trackIdx, trackIdxOK)
...@@ -848,28 +865,27 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -848,28 +865,27 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
keys1.Add(tAllKeyv[idx1]) keys1.Add(tAllKeyv[idx1])
} }
t.Run(fmt.Sprintf(" track=%s;R", keys1), func(t *testing.T) { t.Run(fmt.Sprintf(" T(%s);R", keys1), func(t *testing.T) {
δbtail := NewΔBtail(t0.at, db) δbtail := NewΔBtail(t0.at, db)
// assert trackIdx=ø, newTrackIdx=ø, vδB=[] // assert trackIdx=ø, trackNew=ø, vδB=[]
δbtail.assertTrack(t, "@at0", ø, ø) // XXX + vδB δbtail.assertTrack(t, "@at0", ø, ø) // XXX + vδB
step1 := func() { // XXX will be not needed with clone
xverifyΔBTail_rebuild1(t, db, δbtail, t0, t1, treeRoot, xat, xverifyΔBTail_rebuild1(t, db, δbtail, t0, t1, treeRoot, xat,
// after Update(t0->t1): // after Update(t0->t1):
/*trackIdx=*/ ø, /*trackIdx=*/ ø,
// after Track(keys) // after Track(keys)
keys1, keys1,
/*newTrackIdx=*/ t1.xkv.trackIdx(keys1), /*trackNew=*/ t1.xkv.trackIdx(keys1),
// after rebuild // after rebuild
/*trackIdx=*/ t1.xkv.trackIdx(keys1), /*trackIdx=*/ t1.xkv.trackIdx(keys1),
/*vδB=*/ /*XXX temp*/nil /*[δ1/Tadj(keys1)*/) /*vδB=*/ /*XXX temp*/nil /*[δ1/Tadj(keys1)*/)
}
assertTrack(t, "@at1 trackIdx", δbtail.trackIdx, t1.xkv.trackIdx(keys1)) step1()
/* TODO reenable
// tRestKeys2 = tAllKeys - keys1 // tRestKeys2 = tAllKeys - keys1
tRestKeys2 := tAllKeys.Difference(keys1) tRestKeys2 := tAllKeys.Difference(keys1)
tRestKeyv2 := tRestKeys2.SortedElements() tRestKeyv2 := tRestKeys2.SortedElements()
...@@ -879,13 +895,33 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -879,13 +895,33 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
keys2.Add(tRestKeyv2[idx2]) keys2.Add(tRestKeyv2[idx2])
} }
δbtail_ = δbtail.Clone() t.Run(fmt.Sprintf(" →%s T(%s);R", t2.tree, keys2), func(t *testing.T) {
// XXX t.Run
xverifyΔBTail_rebuild1(t, δbtail_, t1, t2, keys, // XXX implement Clone and go the clone way if test starts running too slow
trackIdx==Tadj(t2,Tadj(t1,keys1)) v Tadj(t2,keys2), //δbtail_ := δbtail.Clone()
vδΒ=[δ1/keys1+keys2, δ2/keys1+keys2]) δbtail = NewΔBtail(t0.at, db)
step1()
δbtail_ := δbtail
// tracked keys1 becomes tracked keys1_2 after Update(t1->t2)
keys1_2 := kadj12.Map(keys1)
xverifyΔBTail_rebuild1(t, db, δbtail_, t1, t2, treeRoot, xat,
// after Update(t1->t2):
/*trackIdx=*/ t2.xkv.trackIdx(keys1_2),
// after Track(keys2)
keys2,
// FIXME vvv trackNew should not cover ranges that are already in trackIdx
/*trackNew*/ t2.xkv.trackIdx(keys2),
// after rebuild
/* trackIdx=*/ t2.xkv.trackIdx(keys1_2.Union(keys2)),
/*vδB=*/ /*XXX temp*/nil /*[δ1/keys1+keys2, δ2/keys1+keys2]*/)
})
} }
*/
}) })
} }
}) })
...@@ -894,7 +930,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -894,7 +930,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// xverifyΔBTail_rebuild1 verifies ΔBTree state: // xverifyΔBTail_rebuild1 verifies ΔBTree state:
// 1. after Update(ti->tj), // 1. after Update(ti->tj),
// 2. after further Track(keys), rebuild // 2. after further Track(keys), rebuild
func xverifyΔBTail_rebuild1(t *testing.T, db *zodb.DB, δbtail *ΔBtail, ti, tj *tTreeCommit, treeRoot zodb.Oid, xat map[zodb.Tid]string, trackIdx trackIndex, keys SetKey, newTrackIdx, trackIdxAfterRebuild trackIndex,vδBok []ΔB) { func xverifyΔBTail_rebuild1(t *testing.T, db *zodb.DB, δbtail *ΔBtail, ti, tj *tTreeCommit, treeRoot zodb.Oid, xat map[zodb.Tid]string, trackIdx trackIndex, keys SetKey, trackNew, trackIdxAfterRebuild trackIndex,vδBok []ΔB) {
X := exc.Raiseif X := exc.Raiseif
ø := trackIndex{} ø := trackIndex{}
...@@ -916,7 +952,7 @@ func xverifyΔBTail_rebuild1(t *testing.T, db *zodb.DB, δbtail *ΔBtail, ti, tj ...@@ -916,7 +952,7 @@ func xverifyΔBTail_rebuild1(t *testing.T, db *zodb.DB, δbtail *ΔBtail, ti, tj
err = δbtail.Track(k, ok, path); X(err) err = δbtail.Track(k, ok, path); X(err)
} }
δbtail.assertTrack(t, fmt.Sprintf("@%s: after Track(%v)", xat[tj.at], keys), trackIdx, newTrackIdx) δbtail.assertTrack(t, fmt.Sprintf("@%s: after Track(%v)", xat[tj.at], keys), trackIdx, trackNew)
// XXX vδB=[ø] // XXX vδB=[ø]
δbtail.rebuild() δbtail.rebuild()
......
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