Commit d587b035 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 496c7632
...@@ -28,42 +28,45 @@ import ( ...@@ -28,42 +28,45 @@ import (
const traceRangeSet = false const traceRangeSet = false
const debugRangeSet = false const debugRangeSet = false
// Range represents [lo,hi) Key range. // KeyRange represents [lo,hi) Key range.
// XXX -> KeyRange? type KeyRange struct {
type Range struct {
lo Key lo Key
hi_ Key // NOTE _not_ hi) to avoid overflow at ∞; hi = hi_ + 1 hi_ Key // NOTE _not_ hi) to avoid overflow at ∞; hi = hi_ + 1
} }
// RangeSet is set of Keys with adjacent keys coaleced into Ranges. // RangedKeySet is set of Keys with adjacent keys coaleced into Ranges.
// //
// Zero value represents empty set. // Zero value represents empty set.
// XXX -> RangedSet ? RangedKeySet ? RangeKeySet? type RangedKeySet struct {
type RangeSet struct {
// TODO rework to use BTree lo->hi_ instead if in practice in treediff, // TODO rework to use BTree lo->hi_ instead if in practice in treediff,
// and other usage places, N(ranges) turns out to be not small // and other usage places, N(ranges) turns out to be not small
// (i.e. performance turns out to be not acceptable) // (i.e. performance turns out to be not acceptable)
rangev []Range // lo↑ rangev []KeyRange // lo↑
} }
/* XXX temp - reenable
// Add adds key k to the set. // Add adds key k to the set.
func (S *RangeSet) Add(k Key) { func (S *RangedKeySet) Add(k Key) {
S.AddRange(Range{lo: k, hi_: k}) S.AddRange(KeyRange{lo: k, hi_: k})
} }
// Del removes key k from the set. // Del removes key k from the set.
func (S *RangeSet) Del(k Key) { func (S *RangedKeySet) Del(k Key) {
S.DelRange(Range{lo: k, hi_: k}) S.DelRange(KeyRange{lo: k, hi_: k})
} }
// Has returns whether key k belongs to the set. // Has returns whether key k belongs to the set.
func (S *RangeSet) Has(k Key) bool { func (S *RangedKeySet) Has(k Key) bool {
return S.HasRange(Range{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.
func (S *RangeSet) AddRange(r Range) { func (S *RangedKeySet) AddRange(r KeyRange) {
if traceRangeSet { if traceRangeSet {
fmt.Printf("\n\nAddRange:\n") fmt.Printf("\n\nAddRange:\n")
fmt.Printf(" S: %s\n", S) fmt.Printf(" S: %s\n", S)
...@@ -105,8 +108,8 @@ func (S *RangeSet) AddRange(r Range) { ...@@ -105,8 +108,8 @@ func (S *RangeSet) AddRange(r Range) {
lo := S.rangev[ilo].lo lo := S.rangev[ilo].lo
hi_ := S.rangev[jhi-1].hi_ hi_ := S.rangev[jhi-1].hi_
S.rangev = append( S.rangev = append(
S.rangev[:ilo], append([]Range{ S.rangev[:ilo], append([]KeyRange{
Range{lo, hi_}}, KeyRange{lo, hi_}},
S.rangev[jhi:]...)...) S.rangev[jhi:]...)...)
debugfRSet("\tmerge S[%d:%d]\t-> %s\n", ilo, jhi, S) debugfRSet("\tmerge S[%d:%d]\t-> %s\n", ilo, jhi, S)
} }
...@@ -115,7 +118,7 @@ func (S *RangeSet) AddRange(r Range) { ...@@ -115,7 +118,7 @@ func (S *RangeSet) AddRange(r Range) {
// if [r.lo,r.hi) was outside of any entry - create new entry // if [r.lo,r.hi) was outside of any entry - create new entry
if r.hi_ < S.rangev[ilo].lo { if r.hi_ < S.rangev[ilo].lo {
S.rangev = append( S.rangev = append(
S.rangev[:ilo], append([]Range{ S.rangev[:ilo], append([]KeyRange{
r}, r},
S.rangev[ilo:]...)...) S.rangev[ilo:]...)...)
debugfRSet("\tinsert %s\t-> %s\n", r, S) debugfRSet("\tinsert %s\t-> %s\n", r, S)
...@@ -136,8 +139,8 @@ func (S *RangeSet) AddRange(r Range) { ...@@ -136,8 +139,8 @@ func (S *RangeSet) AddRange(r Range) {
if ilo+1 < len(S.rangev) { // right if ilo+1 < len(S.rangev) { // right
if S.rangev[ilo].hi_+1 == S.rangev[ilo+1].lo { if S.rangev[ilo].hi_+1 == S.rangev[ilo+1].lo {
S.rangev = append( S.rangev = append(
S.rangev[:ilo], append([]Range{ S.rangev[:ilo], append([]KeyRange{
Range{S.rangev[ilo].lo, S.rangev[ilo+1].hi_}}, KeyRange{S.rangev[ilo].lo, S.rangev[ilo+1].hi_}},
S.rangev[ilo+2:]...)...) S.rangev[ilo+2:]...)...)
debugfRSet("\tmerge right\t-> %s\n", S) debugfRSet("\tmerge right\t-> %s\n", S)
} }
...@@ -146,8 +149,8 @@ func (S *RangeSet) AddRange(r Range) { ...@@ -146,8 +149,8 @@ func (S *RangeSet) AddRange(r Range) {
if ilo > 0 { // left if ilo > 0 { // left
if S.rangev[ilo-1].hi_+1 == S.rangev[ilo].lo { if S.rangev[ilo-1].hi_+1 == S.rangev[ilo].lo {
S.rangev = append( S.rangev = append(
S.rangev[:ilo-1], append([]Range{ S.rangev[:ilo-1], append([]KeyRange{
Range{S.rangev[ilo-1].lo, S.rangev[ilo].hi_}}, KeyRange{S.rangev[ilo-1].lo, S.rangev[ilo].hi_}},
S.rangev[ilo+1:]...)...) S.rangev[ilo+1:]...)...)
debugfRSet("\tmerge left\t-> %s\n", S) debugfRSet("\tmerge left\t-> %s\n", S)
} }
...@@ -156,8 +159,8 @@ func (S *RangeSet) AddRange(r Range) { ...@@ -156,8 +159,8 @@ func (S *RangeSet) AddRange(r Range) {
// done // done
} }
// DelRange removes Range r from the set. // DelRange removes range r from the set.
func (S *RangeSet) DelRange(r Range) { func (S *RangedKeySet) DelRange(r KeyRange) {
if traceRangeSet { if traceRangeSet {
fmt.Printf("\n\nDelRange:\n") fmt.Printf("\n\nDelRange:\n")
fmt.Printf(" S: %s\n", S) fmt.Printf(" S: %s\n", S)
...@@ -204,7 +207,7 @@ func (S *RangeSet) DelRange(r Range) { ...@@ -204,7 +207,7 @@ func (S *RangeSet) DelRange(r Range) {
if jhi-ilo == 1 && S.rangev[ilo].lo < r.lo && r.hi_ < S.rangev[ilo].hi_ { if jhi-ilo == 1 && S.rangev[ilo].lo < r.lo && r.hi_ < S.rangev[ilo].hi_ {
x := S.rangev[ilo] x := S.rangev[ilo]
S.rangev = append( S.rangev = append(
S.rangev[:ilo], append([]Range{ S.rangev[:ilo], append([]KeyRange{
x, x}, x, x},
S.rangev[ilo+1:]...)...) S.rangev[ilo+1:]...)...)
jhi++ jhi++
...@@ -212,16 +215,16 @@ func (S *RangeSet) DelRange(r Range) { ...@@ -212,16 +215,16 @@ func (S *RangeSet) DelRange(r Range) {
} }
if S.rangev[ilo].lo < r.lo { // shrink left if S.rangev[ilo].lo < r.lo { // shrink left
S.rangev = append( S.rangev = append(
S.rangev[:ilo], append([]Range{ S.rangev[:ilo], append([]KeyRange{
Range{S.rangev[ilo].lo, r.lo-1}}, KeyRange{S.rangev[ilo].lo, r.lo-1}},
S.rangev[ilo+1:]...)...) S.rangev[ilo+1:]...)...)
ilo++ ilo++
debugfRSet("\tshrink [%d] left\t-> %s\n", ilo, S) debugfRSet("\tshrink [%d] left\t-> %s\n", ilo, S)
} }
if r.hi_ < S.rangev[jhi-1].hi_ { // shrink right if r.hi_ < S.rangev[jhi-1].hi_ { // shrink right
S.rangev = append( S.rangev = append(
S.rangev[:jhi-1], append([]Range{ S.rangev[:jhi-1], append([]KeyRange{
Range{r.hi_+1, S.rangev[jhi-1].hi_}}, KeyRange{r.hi_+1, S.rangev[jhi-1].hi_}},
S.rangev[jhi:]...)...) S.rangev[jhi:]...)...)
jhi-- jhi--
debugfRSet("\tshrink [%d] right\t-> %s\n", jhi-1, S) debugfRSet("\tshrink [%d] right\t-> %s\n", jhi-1, S)
...@@ -237,8 +240,8 @@ func (S *RangeSet) DelRange(r Range) { ...@@ -237,8 +240,8 @@ func (S *RangeSet) DelRange(r Range) {
// done // done
} }
// HasRange returns whether all keys from Range r belong to the set. // HasRange returns whether all keys from range r belong to the set.
func (S *RangeSet) HasRange(r Range) (yes bool) { func (S *RangedKeySet) HasRange(r KeyRange) (yes bool) {
if traceRangeSet { if traceRangeSet {
fmt.Printf("\n\nHasRange:\n") fmt.Printf("\n\nHasRange:\n")
fmt.Printf(" S: %s\n", S) fmt.Printf(" S: %s\n", S)
...@@ -266,15 +269,15 @@ func (S *RangeSet) HasRange(r Range) (yes bool) { ...@@ -266,15 +269,15 @@ func (S *RangeSet) HasRange(r Range) (yes bool) {
} }
// Union returns RangeSet(A.keys | B.keys). // Union returns RangedKeySet(A.keys | B.keys).
func (A *RangeSet) Union(B *RangeSet) *RangeSet { func (A *RangedKeySet) Union(B *RangedKeySet) *RangedKeySet {
U := A.Clone() U := A.Clone()
U.UnionInplace(B) U.UnionInplace(B)
return U return U
} }
// Difference returns RangeSet(A.keys \ B.keys). // Difference returns RangedKeySet(A.keys \ B.keys).
func (A *RangeSet) Difference(B *RangeSet) *RangeSet { func (A *RangedKeySet) Difference(B *RangedKeySet) *RangedKeySet {
D := A.Clone() D := A.Clone()
D.DifferenceInplace(B) D.DifferenceInplace(B)
return D return D
...@@ -282,7 +285,7 @@ func (A *RangeSet) Difference(B *RangeSet) *RangeSet { ...@@ -282,7 +285,7 @@ func (A *RangeSet) Difference(B *RangeSet) *RangeSet {
// XXX Intersection // XXX Intersection
func (A *RangeSet) UnionInplace(B *RangeSet) { func (A *RangedKeySet) UnionInplace(B *RangedKeySet) {
A.verify() A.verify()
B.verify() B.verify()
defer A.verify() defer A.verify()
...@@ -293,7 +296,7 @@ func (A *RangeSet) UnionInplace(B *RangeSet) { ...@@ -293,7 +296,7 @@ func (A *RangeSet) UnionInplace(B *RangeSet) {
} }
} }
func (A *RangeSet) DifferenceInplace(B *RangeSet) { func (A *RangedKeySet) DifferenceInplace(B *RangedKeySet) {
A.verify() A.verify()
B.verify() B.verify()
defer A.verify() defer A.verify()
...@@ -310,9 +313,9 @@ func (A *RangeSet) DifferenceInplace(B *RangeSet) { ...@@ -310,9 +313,9 @@ func (A *RangeSet) DifferenceInplace(B *RangeSet) {
// -------- // --------
// verify check RangeSet for internal consistency: // verify check RangedKeySet for internal consistency:
// - ranges must be not overlapping nor adjacent and ↑ // - ranges must be not overlapping nor adjacent and ↑
func (S *RangeSet) verify() { func (S *RangedKeySet) verify() {
// XXX !debug -> return ? // XXX !debug -> return ?
var badv []string var badv []string
...@@ -344,19 +347,19 @@ func (S *RangeSet) verify() { ...@@ -344,19 +347,19 @@ func (S *RangeSet) verify() {
} }
// Clone returns copy of the set. // Clone returns copy of the set.
func (orig *RangeSet) Clone() *RangeSet { func (orig *RangedKeySet) Clone() *RangedKeySet {
klon := &RangeSet{} klon := &RangedKeySet{}
klon.rangev = append(klon.rangev, orig.rangev...) klon.rangev = append(klon.rangev, orig.rangev...)
return klon return klon
} }
// Empty returns whether the set is empty. // Empty returns whether the set is empty.
func (S *RangeSet) Empty() bool { func (S *RangedKeySet) Empty() bool {
return len(S.rangev) == 0 return len(S.rangev) == 0
} }
// Equal returns whether A == B. // Equal returns whether A == B.
func (A *RangeSet) Equal(B *RangeSet) bool { func (A *RangedKeySet) Equal(B *RangedKeySet) bool {
if len(A.rangev) != len(B.rangev) { if len(A.rangev) != len(B.rangev) {
return false return false
} }
...@@ -370,11 +373,11 @@ func (A *RangeSet) Equal(B *RangeSet) bool { ...@@ -370,11 +373,11 @@ func (A *RangeSet) Equal(B *RangeSet) bool {
} }
// Clear removes all elements from the set. // Clear removes all elements from the set.
func (S *RangeSet) Clear() { func (S *RangedKeySet) Clear() {
S.rangev = nil S.rangev = nil
} }
func (S RangeSet) String() string { func (S RangedKeySet) String() string {
s := "{" s := "{"
for i, r := range S.rangev { for i, r := range S.rangev {
if i > 0 { if i > 0 {
...@@ -386,7 +389,7 @@ func (S RangeSet) String() string { ...@@ -386,7 +389,7 @@ func (S RangeSet) String() string {
return s return s
} }
func (r Range) String() string { func (r KeyRange) String() string {
slo := "-∞"; if r.lo > KeyMin { slo = fmt.Sprintf("%v", r.lo) } slo := "-∞"; if r.lo > KeyMin { slo = fmt.Sprintf("%v", r.lo) }
shi := "∞"; if r.hi_ < KeyMax { shi = fmt.Sprintf("%v", r.hi_+1) } shi := "∞"; if r.hi_ < KeyMax { shi = fmt.Sprintf("%v", r.hi_+1) }
return fmt.Sprintf("[%s,%s)", slo, shi) return fmt.Sprintf("[%s,%s)", slo, shi)
......
...@@ -23,28 +23,28 @@ import ( ...@@ -23,28 +23,28 @@ import (
"testing" "testing"
) )
func TestRangeSet(t *testing.T) { func TestRangedKeySet(t *testing.T) {
const ( const (
oo = KeyMax oo = KeyMax
noo = KeyMin noo = KeyMin
) )
type testEntry struct { type testEntry struct {
A, B *RangeSet A, B *RangedKeySet
Union *RangeSet Union *RangedKeySet
Difference *RangeSet Difference *RangedKeySet
} }
E := func(A, B, U, D *RangeSet) testEntry { E := func(A, B, U, D *RangedKeySet) testEntry {
return testEntry{A, B, U, D} return testEntry{A, B, U, D}
} }
// S is shorthand to create RangeSet, e.g. S(1,2, 4,5) will return {[1,2) [4,5)} // S is shorthand to create RangedKeySet, e.g. S(1,2, 4,5) will return {[1,2) [4,5)}
S := func(kv ...Key) *RangeSet { S := func(kv ...Key) *RangedKeySet {
l := len(kv) l := len(kv)
if l % 2 != 0 { if l % 2 != 0 {
panic("odd number of keys") panic("odd number of keys")
} }
S := &RangeSet{} S := &RangedKeySet{}
for i := 0; i < l/2; i++ { for i := 0; i < l/2; i++ {
// construct .rangev directly, not via AddRange // construct .rangev directly, not via AddRange
lo := kv[2*i] lo := kv[2*i]
...@@ -53,7 +53,7 @@ func TestRangeSet(t *testing.T) { ...@@ -53,7 +53,7 @@ func TestRangeSet(t *testing.T) {
if hi_ != oo { if hi_ != oo {
hi_-- hi_--
} }
S.rangev = append(S.rangev, Range{lo, hi_}) S.rangev = append(S.rangev, KeyRange{lo, hi_})
} }
S.verify() S.verify()
return S return S
...@@ -145,7 +145,7 @@ func TestRangeSet(t *testing.T) { ...@@ -145,7 +145,7 @@ func TestRangeSet(t *testing.T) {
} }
// assertHasRange asserts for all ranges from rangev that S.HasRange(r) == hasOK // assertHasRange asserts for all ranges from rangev that S.HasRange(r) == hasOK
func assertHasRange(t *testing.T, rangev []Range, S *RangeSet, hasOK bool) { func assertHasRange(t *testing.T, rangev []KeyRange, S *RangedKeySet, hasOK bool) {
t.Helper() t.Helper()
for _, r := range rangev { for _, r := range rangev {
has := S.HasRange(r) has := S.HasRange(r)
......
...@@ -177,7 +177,7 @@ func δZConnectTracked(δZv []zodb.Oid, T PPTreeSubSet) (δZTC SetOid, δtopsByR ...@@ -177,7 +177,7 @@ func δZConnectTracked(δZv []zodb.Oid, T PPTreeSubSet) (δZTC SetOid, δtopsByR
// nodeInRange represents a Node coming under [lo, hi_] key range in its tree. // nodeInRange represents a Node coming under [lo, hi_] key range in its tree.
type nodeInRange struct { type nodeInRange struct {
prefix []zodb.Oid // path to this node goes via this objects prefix []zodb.Oid // path to this node goes via this objects
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ XXX -> Range
node Node node Node
done bool // whether this node was already taken into account while computing diff done bool // whether this node was already taken into account while computing diff
} }
...@@ -520,20 +520,28 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -520,20 +520,28 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
Bv := rangeSplit{btop} // nodes expanded from B Bv := rangeSplit{btop} // nodes expanded from B
// for phase 2: // for phase 2:
Akqueue := &RangeSet{} // queue for keys in A to be processed for δ- Akqueue := &RangedKeySet{} // queue for keys in A to be processed for δ-
Bkqueue := &RangeSet{} // ----//---- in B for δ+ Bkqueue := &RangedKeySet{} // ----//---- in B for δ+
Akdone := &RangeSet{} // already processed keys in A Akdone := &RangedKeySet{} // already processed keys in A
Bkdone := &RangeSet{} // ----//---- in B Bkdone := &RangedKeySet{} // ----//---- in B
Aktodo := func(k Key) { Aktodo := func(r KeyRange) {
if !Akdone.HasRange(r) {
δtodo := &RangedKeySet{}
δtodo.AddRange(r)
δtodo.DifferenceInplace(Akdone)
tracef(" Akq <- %d\n", δtodo)
Akqueue.UnionInplace(δtodo)
}
/* XXX kill
if !Akdone.Has(k) { if !Akdone.Has(k) {
tracef(" Akq <- %d\n", k) tracef(" Akq <- %d\n", k)
Akqueue.Add(k) Akqueue.Add(k)
} }
*/
} }
Bktodo := func(lo, hi_ Key) { // XXX -> func(r Range) Bktodo := func(r KeyRange) {
r := Range{lo, hi_}
if !Bkdone.HasRange(r) { if !Bkdone.HasRange(r) {
δtodo := &RangeSet{} δtodo := &RangedKeySet{}
δtodo.AddRange(r) δtodo.AddRange(r)
δtodo.DifferenceInplace(Bkdone) δtodo.DifferenceInplace(Bkdone)
tracef(" Bkq <- %s\n", δtodo) tracef(" Bkq <- %s\n", δtodo)
...@@ -588,13 +596,13 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -588,13 +596,13 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
} }
*/ */
// Bkqueue <- ra.range // Bkqueue <- ra.range
Bktodo(ra.lo, ra.hi_) Bktodo(KeyRange{ra.lo, ra.hi_})
ra.done = true ra.done = true
case *Tree: case *Tree:
// empty tree - only queue holes covered by it // empty tree - only queue holes covered by it
if len(a.Entryv()) == 0 { if len(a.Entryv()) == 0 {
Bktodo(ra.lo, ra.hi_) Bktodo(KeyRange{ra.lo, ra.hi_})
/* XXX kill /* XXX kill
for k := range holeIdx.GetInRange(ra.lo, ra.hi_) { for k := range holeIdx.GetInRange(ra.lo, ra.hi_) {
Bktodo(k) Bktodo(k)
...@@ -722,10 +730,15 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -722,10 +730,15 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtrack.Add.AddPath(b.Path()) δtrack.Add.AddPath(b.Path())
// Akqueue <- δB // Akqueue <- δB
br := KeyRange{b.lo, b.hi_}
Bkdone.AddRange(br)
Aktodo(br)
/*
for k_ := range δB { for k_ := range δB {
Bkdone.Add(k_) Bkdone.Add(k_)
Aktodo(k_) Aktodo(k_)
} }
*/
b.done = true b.done = true
} }
...@@ -752,7 +765,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet) ...@@ -752,7 +765,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtrack.Del.AddPath(a.Path()) δtrack.Del.AddPath(a.Path())
// Bkqueue <- a.range // Bkqueue <- a.range
Bktodo(a.lo, a.hi_) Bktodo(KeyRange{a.lo, a.hi_})
/* XXX kill /* XXX kill
// Bkqueue <- δA // Bkqueue <- δA
for k_ := range δA { for k_ := range δA {
......
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