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

.

parent 29a5ab55
...@@ -45,7 +45,12 @@ type RangedKeySet struct { ...@@ -45,7 +45,12 @@ type RangedKeySet struct {
} }
/* XXX temp - reenable ///* XXX temp - reenable
// Has returns whether key k belongs to the range.
func (r *KeyRange) Has(k Key) bool {
return (r.lo <= k && k <= r.hi_)
}
// Add adds key k to the set. // Add adds key k to the set.
func (S *RangedKeySet) Add(k Key) { func (S *RangedKeySet) Add(k Key) {
...@@ -62,7 +67,7 @@ func (S *RangedKeySet) Has(k Key) bool { ...@@ -62,7 +67,7 @@ func (S *RangedKeySet) Has(k Key) bool {
return S.HasRange(KeyRange{lo: k, hi_: k}) return S.HasRange(KeyRange{lo: k, hi_: k})
} }
*/ //*/
// AddRange adds range r to the set. // AddRange adds range r to the set.
......
...@@ -699,9 +699,6 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -699,9 +699,6 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
// * +B12, which queues A.2 and leads to // * +B12, which queues A.2 and leads to
// * -B23, which queues B.3 and leads to // * -B23, which queues B.3 and leads to
// * +B23, ... // * +B23, ...
//
// XXX inefficient: we process each key separately, while they can be
// processed in sorted batches.
tracef("\nphase 2:\n") tracef("\nphase 2:\n")
for { for {
tracef("\n") tracef("\n")
...@@ -797,6 +794,15 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -797,6 +794,15 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
a.done = true a.done = true
} }
/*
// continue with next right bucket until r coverage is complete
lo = a.hi_ + 1
if r.hi_ <= lo {
break
}
*/
// XXX change vvv to ^^^
// stop if r coverage is complete // stop if r coverage is complete
if r.hi_ <= a.hi_ { if r.hi_ <= a.hi_ {
break break
......
...@@ -263,7 +263,7 @@ type RTree struct { ...@@ -263,7 +263,7 @@ type RTree struct {
type RBucket struct { type RBucket struct {
oid zodb.Oid oid zodb.Oid
parent *RTree parent *RTree
lo, hi_ Key lo, hi_ Key // XXX -> KeyRange ?
kv map[Key]string // bucket's k->v; values were ZBlk objects whose data is loaded instead. kv map[Key]string // bucket's k->v; values were ZBlk objects whose data is loaded instead.
} }
...@@ -491,15 +491,15 @@ func XGetδKV(db *zodb.DB, at1, at2 zodb.Tid, δkvOid map[Key]ΔValue) map[Key] ...@@ -491,15 +491,15 @@ func XGetδKV(db *zodb.DB, at1, at2 zodb.Tid, δkvOid map[Key]ΔValue) map[Key]
// Av, Bv - topologies with values ex T/B1:a T2/B1:b-B3:c // 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 -> ø // δ(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? // ex δ(T/B1:a, T2/B1:b-B3:c) = {-1:a +1:b +3:c}
// //
// Δ(T, Av, Bv) - subset of δ(Av, Bv) corresponding to initial tracking set T // Δ(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) // ex Δ({1}, T/B1:a, T2/B1:b-B3:c) = {-1:a +1:b} (no +3:c)
// //
// kadj(A,B) {} k -> {k'}: - adjacency matrix // kadj(A,B) {} k -> {k'}: - adjacency matrix
// ∃v1,v2: k'∈ Δ({k}, Av1, Bv2) // ∃v1,v2: k'∈ Δ({k}, Av1, Bv2)
// //
// ex kadj(T/B1, T2/B1-B3) = {1:{1} 3:{1,3} ∞:{1,3}} k ∈ A+B+{∞} // ex kadj(T/B1, T2/B1-B3) = {1:{1} 3:{1,3} ∞:{1,3}} k ∈ A+B+{∞} XXX adjust to new kadj
// + {0:{1} 2:{1,3} + ... all possible keys} // + {0:{1} 2:{1,3} + ... all possible keys}
// //
// Δ(T, Av, Bv) = δ(Av, Bv)/kadj(A,B)[T] // Δ(T, Av, Bv) = δ(Av, Bv)/kadj(A,B)[T]
...@@ -542,7 +542,8 @@ func KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) { ...@@ -542,7 +542,8 @@ func KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) {
return kadj12 return kadj12
} }
func _KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) { // XXX kill after holeIdx removal
func _KAdj_old(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) {
var keys SetKey var keys SetKey
switch len(keysv) { switch len(keysv) {
case 0: case 0:
...@@ -604,6 +605,94 @@ func _KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) { ...@@ -604,6 +605,94 @@ func _KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) {
return kadj return kadj
} }
func _KAdj(t1, t2 *tTreeCommit, keysv ...SetKey) (kadj KAdjMatrix) {
var keys SetKey
switch len(keysv) {
case 0:
keys = allTestKeys(t1, t2)
case 1:
keys = keysv[0]
default:
panic("multiple key sets on the call")
}
// kadj = {} k -> adjacent keys.
// if k is tracked -> changes to adjacents must be in Update(t1->t2).
kadj = KAdjMatrix{}
for k := range keys {
adj1 := SetKey{}
adj2 := SetKey{}
q1 := &RangedKeySet{}; q1.Add(k)
q2 := &RangedKeySet{}; q2.Add(k)
done1 := &RangedKeySet{}
done2 := &RangedKeySet{}
//tracef("\n")
for !q1.Empty() || !q2.Empty() {
//tracef("q1: %v\n", q1)
//tracef("q2: %v\n", q2)
for _, r1 := range q1.AllRanges() {
lo1 := r1.lo
for {
b1 := t1.xkv.Get(lo1)
for k_ := range keys {
if b1.lo <= k_ && k_ <= b1.hi_ {
adj1.Add(k_)
}
}
b1r := KeyRange{b1.lo, b1.hi_}
done1.AddRange(b1r)
// q2 |= (b1.keyrange \ done2)
δq2 := &RangedKeySet{}
δq2.AddRange(b1r)
δq2.DifferenceInplace(done2)
q2.UnionInplace(δq2)
// continue with next right bucket until r1 coverage is complete
lo1 = b1.hi_ + 1
if r1.hi_ <= lo1 {
break
}
}
}
q1.Clear()
for _, r2 := range q2.AllRanges() {
lo2 := r2.lo
for {
b2 := t2.xkv.Get(lo2)
for k_ := range keys {
if b2.lo <= k_ && k_ <= b2.hi_ {
adj2.Add(k_)
}
}
b2r := KeyRange{b2.lo, b2.hi_}
done2.AddRange(b2r)
// q1 |= (b2.keyrange \ done1)
δq1 := &RangedKeySet{}
δq1.AddRange(b2r)
δq1.DifferenceInplace(done1)
q1.UnionInplace(δq1)
// continue with next right bucket until r2 coverage is complete
lo2 = b2.hi_ + 1
if r2.hi_ <= lo2 {
break
}
}
}
q2.Clear()
}
adj := SetKey{}; adj.Add(k); adj.Update(adj1); adj.Update(adj2)
kadj[k] = adj
}
return kadj
}
// xverifyΔBTail_Update verifies how ΔBTail handles ZODB update for a tree with changes in between t1->t2. // xverifyΔBTail_Update verifies how ΔBTail handles ZODB update for a tree with changes in between t1->t2.
func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, t1, t2 *tTreeCommit) { func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid, t1, t2 *tTreeCommit) {
...@@ -1358,6 +1447,7 @@ func TestΔBTail(t *testing.T) { ...@@ -1358,6 +1447,7 @@ func TestΔBTail(t *testing.T) {
// test known cases going through tree1 -> tree2 -> ... // test known cases going through tree1 -> tree2 -> ...
testv := []interface{} { testv := []interface{} {
///*
// start from non-empty tree to verify both ->empty and empty-> transitions // start from non-empty tree to verify both ->empty and empty-> transitions
"T/B1:a,2:b", "T/B1:a,2:b",
...@@ -1380,6 +1470,7 @@ func TestΔBTail(t *testing.T) { ...@@ -1380,6 +1470,7 @@ func TestΔBTail(t *testing.T) {
A{1: K(1,2), A{1: K(1,2),
2: K(1,2), 2: K(1,2),
oo: K(1,2,oo)}), oo: K(1,2,oo)}),
//*/
// 2: b->c // 2: b->c
Δ("T/B2:c", Δ("T/B2:c",
......
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