Commit 66bc41ce authored by Kirill Smelkov's avatar Kirill Smelkov

X Fix bug in PPTreeSubSet.Difference - it was always leaving root node alive

So that even A \ A was not ø.
parent 7533257b
......@@ -27,6 +27,7 @@ import (
)
const tracePPSet = false
const debugPPSet = false
// PPTreeSubSet represents PP-connected subset of tree node objects.
//
......@@ -291,10 +292,16 @@ func (A PPTreeSubSet) fixup(δnchild map[zodb.Oid]int) {
A.xfixup(+1, δnchild)
}
func (A PPTreeSubSet) xfixup(sign int, δnchild map[zodb.Oid]int) {
//fmt.Printf("\nfixup:\n")
//fmt.Printf(" ·: %s\n", A)
//fmt.Printf(" δ: %v\n", δnchild)
//defer fmt.Printf(" ->·: %s\n\n", A)
if debugPPSet {
ssign := "+"
if sign < 0 {
ssign = "-"
}
fmt.Printf("\n fixup:\n")
fmt.Printf(" ·: %s\n", A)
fmt.Printf(" %sδ: %v\n", ssign, δnchild)
defer fmt.Printf(" ->·: %s\n\n", A)
}
gcq := []zodb.Oid{}
for oid, δnc := range δnchild {
......@@ -326,7 +333,8 @@ func (S PPTreeSubSet) gc1(oid zodb.Oid) {
for oid != zodb.InvalidOid {
t := S[oid]
t.nchild--
if t.nchild > 0 || /* root node */t.parent == zodb.InvalidOid {
// if t.nchild > 0 || /* root node */t.parent == zodb.InvalidOid {
if t.nchild > 0 {
break
}
delete(S, oid)
......
......@@ -20,6 +20,7 @@
package xbtree
import (
"strings"
"testing"
"lab.nexedi.com/kirr/neo/go/zodb"
......@@ -79,18 +80,42 @@ func TestPPTreeSubSetOps(t *testing.T) {
S{a:{ø,1}, b:{a,0}}, // B
S{a:{ø,1}, b:{a,0}}, // U
S{}), // D
E(
S{a:{ø,1}, b:{a,1}, c:{b,0}}, // A
S{a:{ø,1}, b:{a,1}, c:{b,0}}, // B (=A)
S{a:{ø,1}, b:{a,1}, c:{b,0}}, // U (=A)
S{}), // D
}
assert1 := func(op string, A, B, res, resOK S) {
t.Helper()
if res.Equal(resOK) {
return
}
op1 := op[0:1]
t.Errorf("%s:\n A: %s\n B: %s\n ->%s: %s\n ok%s: %s\n",
strings.Title(op), A, B, op1, res, strings.ToUpper(op1), resOK)
}
for _, tt := range testv {
U := tt.A.Union(tt.B)
D := tt.A.Difference(tt.B)
Uab := tt.A.Union(tt.B)
Uba := tt.B.Union(tt.A)
Dab := tt.A.Difference(tt.B)
if !U.Equal(tt.Union) {
t.Errorf("Union:\n A: %s\n B: %s\n ->u: %s\n okU: %s\n", tt.A, tt.B, U, tt.Union)
}
if !D.Equal(tt.Difference) {
t.Errorf("Difference:\n A: %s\n B: %s\n ->d: %s\n okD: %s\n", tt.A, tt.B, D, tt.Difference)
}
assert1("union", tt.A, tt.B, Uab, tt.Union)
assert1("union", tt.B, tt.A, Uba, tt.Union)
assert1("difference", tt.A, tt.B, Dab, tt.Difference)
Uaa := tt.A.Union(tt.A)
Ubb := tt.B.Union(tt.B)
Daa := tt.A.Difference(tt.A)
Dbb := tt.B.Difference(tt.B)
assert1("union", tt.A, tt.A, Uaa, tt.A)
assert1("union", tt.B, tt.B, Ubb, tt.B)
assert1("difference", tt.A, tt.A, Daa, S{})
assert1("difference", tt.B, tt.B, Dbb, S{})
// XXX also verify U/D properties like (A+B)\B + (A+B)\A + (A^B) == (A+B) ?
}
......
......@@ -159,7 +159,7 @@ func δZConnectTracked(δZv []zodb.Oid, T PPTreeSubSet) (δZTC SetOid, δtopsByR
// nodeInRange represents a Node coming under [lo, hi_] key range in its tree.
type nodeInRange struct {
prefix []zodb.Oid // path to this node goes via this objects
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ XXX -> Range
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ XXX -> keycov KeyRange?
node Node
done bool // whether this node was already taken into account while computing diff
}
......
......@@ -1042,11 +1042,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
}
}
// // tracked keys1 becomes tracked keys1_2 after Update(t1->t2)
//// keys1_2 := kadj12.Map(keys1)
// keys1_2 := kadj12.Map(kadj01.Map(keys1_0))
xverifyΔBTail_rebuild_U(t, δbtail, db, treeRoot, t1, t2, xat,
// /*trackSet=*/t2.xkv.trackSet(keys1_2),
/*trackSet=*/t2.xkv.trackSet(keys1R2),
/*vδT=*/ δkv1_k1R2, δkv2_k1R2)
......@@ -1070,23 +1066,22 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
keys12R2 = keys12R2_
}
// // δkv1_2 = t1.δxkv / kadj10(kadj21(kadj12(keys1) | keys2))
// // δkv2_2 = t2.δxkv / kadj10(kadj21(kadj12(keys1) | keys2))
//// keys12_2 := keys1_2.Union(keys2)
//// keys12_0 := kadj10.Map(kadj21.Map(keys12_2))
/*
///*
fmt.Printf("\n\n\nKKK\nkeys1=%s keys2=%s\n", keys1, keys2)
fmt.Printf("keys12R2=%s\n", keys12R2)
fmt.Printf("keys1R2: %s\n", keys1R2)
fmt.Printf("keys12R2: %s\n", keys12R2)
fmt.Printf("t0.xkv: %v\n", t0.xkv)
fmt.Printf("t1.xkv: %v\n", t1.xkv)
fmt.Printf("t2.xkv: %v\n", t2.xkv)
fmt.Printf("kadj21: %v\n", kadj21)
fmt.Printf("kadj12: %v\n", kadj12)
fmt.Printf("t2.xkv.trackSet(%s) -> %s", keys12R2, t2.xkv.trackSet(keys12R2))
fmt.Printf("t2.xkv.trackSet(keys2) -> %s\n", t2.xkv.trackSet(keys2))
fmt.Printf("t2.xkv.trackSet(keys1R2) -> %s\n", t2.xkv.trackSet(keys1R2))
fmt.Printf("t2.xkv.trackSet(keys2) \\ t2.xkv.trackSet(keys1R2) -> %s\n",
t2.xkv.trackSet(keys2).Difference(t2.xkv.trackSet(keys1R2)))
fmt.Printf("\n\n\n")
*/
//*/
// δkvX_k12R2 = tX.δxkv / keys12R2
......@@ -1109,12 +1104,10 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
xverifyΔBTail_rebuild_TR(t, db, δbtail_, t2, treeRoot, xat,
// after Track(keys2)
keys2,
// /*trackSet*/ t2.xkv.trackSet(keys1_2),
/*trackSet*/ t2.xkv.trackSet(keys1R2),
/*trackNew*/ t2.xkv.trackSet(keys2).Difference(
// trackNew should not cover ranges that are
// already in trackSet
// t2.xkv.trackSet(keys1_2)),
t2.xkv.trackSet(keys1R2)),
// after 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