Commit d587b035 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 496c7632
......@@ -28,42 +28,45 @@ import (
const traceRangeSet = false
const debugRangeSet = false
// Range represents [lo,hi) Key range.
// XXX -> KeyRange?
type Range struct {
// KeyRange represents [lo,hi) Key range.
type KeyRange struct {
lo Key
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.
// XXX -> RangedSet ? RangedKeySet ? RangeKeySet?
type RangeSet struct {
type RangedKeySet struct {
// 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
// (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.
func (S *RangeSet) Add(k Key) {
S.AddRange(Range{lo: k, hi_: k})
func (S *RangedKeySet) Add(k Key) {
S.AddRange(KeyRange{lo: k, hi_: k})
}
// Del removes key k from the set.
func (S *RangeSet) Del(k Key) {
S.DelRange(Range{lo: k, hi_: k})
func (S *RangedKeySet) Del(k Key) {
S.DelRange(KeyRange{lo: k, hi_: k})
}
// Has returns whether key k belongs to the set.
func (S *RangeSet) Has(k Key) bool {
return S.HasRange(Range{lo: k, hi_: k})
func (S *RangedKeySet) Has(k Key) bool {
return S.HasRange(KeyRange{lo: k, hi_: k})
}
*/
// AddRange adds Range r to the set.
func (S *RangeSet) AddRange(r Range) {
// AddRange adds range r to the set.
func (S *RangedKeySet) AddRange(r KeyRange) {
if traceRangeSet {
fmt.Printf("\n\nAddRange:\n")
fmt.Printf(" S: %s\n", S)
......@@ -105,8 +108,8 @@ func (S *RangeSet) AddRange(r Range) {
lo := S.rangev[ilo].lo
hi_ := S.rangev[jhi-1].hi_
S.rangev = append(
S.rangev[:ilo], append([]Range{
Range{lo, hi_}},
S.rangev[:ilo], append([]KeyRange{
KeyRange{lo, hi_}},
S.rangev[jhi:]...)...)
debugfRSet("\tmerge S[%d:%d]\t-> %s\n", ilo, jhi, S)
}
......@@ -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.hi_ < S.rangev[ilo].lo {
S.rangev = append(
S.rangev[:ilo], append([]Range{
S.rangev[:ilo], append([]KeyRange{
r},
S.rangev[ilo:]...)...)
debugfRSet("\tinsert %s\t-> %s\n", r, S)
......@@ -136,8 +139,8 @@ func (S *RangeSet) AddRange(r Range) {
if ilo+1 < len(S.rangev) { // right
if S.rangev[ilo].hi_+1 == S.rangev[ilo+1].lo {
S.rangev = append(
S.rangev[:ilo], append([]Range{
Range{S.rangev[ilo].lo, S.rangev[ilo+1].hi_}},
S.rangev[:ilo], append([]KeyRange{
KeyRange{S.rangev[ilo].lo, S.rangev[ilo+1].hi_}},
S.rangev[ilo+2:]...)...)
debugfRSet("\tmerge right\t-> %s\n", S)
}
......@@ -146,8 +149,8 @@ func (S *RangeSet) AddRange(r Range) {
if ilo > 0 { // left
if S.rangev[ilo-1].hi_+1 == S.rangev[ilo].lo {
S.rangev = append(
S.rangev[:ilo-1], append([]Range{
Range{S.rangev[ilo-1].lo, S.rangev[ilo].hi_}},
S.rangev[:ilo-1], append([]KeyRange{
KeyRange{S.rangev[ilo-1].lo, S.rangev[ilo].hi_}},
S.rangev[ilo+1:]...)...)
debugfRSet("\tmerge left\t-> %s\n", S)
}
......@@ -156,8 +159,8 @@ func (S *RangeSet) AddRange(r Range) {
// done
}
// DelRange removes Range r from the set.
func (S *RangeSet) DelRange(r Range) {
// DelRange removes range r from the set.
func (S *RangedKeySet) DelRange(r KeyRange) {
if traceRangeSet {
fmt.Printf("\n\nDelRange:\n")
fmt.Printf(" S: %s\n", S)
......@@ -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_ {
x := S.rangev[ilo]
S.rangev = append(
S.rangev[:ilo], append([]Range{
S.rangev[:ilo], append([]KeyRange{
x, x},
S.rangev[ilo+1:]...)...)
jhi++
......@@ -212,16 +215,16 @@ func (S *RangeSet) DelRange(r Range) {
}
if S.rangev[ilo].lo < r.lo { // shrink left
S.rangev = append(
S.rangev[:ilo], append([]Range{
Range{S.rangev[ilo].lo, r.lo-1}},
S.rangev[:ilo], append([]KeyRange{
KeyRange{S.rangev[ilo].lo, r.lo-1}},
S.rangev[ilo+1:]...)...)
ilo++
debugfRSet("\tshrink [%d] left\t-> %s\n", ilo, S)
}
if r.hi_ < S.rangev[jhi-1].hi_ { // shrink right
S.rangev = append(
S.rangev[:jhi-1], append([]Range{
Range{r.hi_+1, S.rangev[jhi-1].hi_}},
S.rangev[:jhi-1], append([]KeyRange{
KeyRange{r.hi_+1, S.rangev[jhi-1].hi_}},
S.rangev[jhi:]...)...)
jhi--
debugfRSet("\tshrink [%d] right\t-> %s\n", jhi-1, S)
......@@ -237,8 +240,8 @@ func (S *RangeSet) DelRange(r Range) {
// done
}
// HasRange returns whether all keys from Range r belong to the set.
func (S *RangeSet) HasRange(r Range) (yes bool) {
// HasRange returns whether all keys from range r belong to the set.
func (S *RangedKeySet) HasRange(r KeyRange) (yes bool) {
if traceRangeSet {
fmt.Printf("\n\nHasRange:\n")
fmt.Printf(" S: %s\n", S)
......@@ -266,15 +269,15 @@ func (S *RangeSet) HasRange(r Range) (yes bool) {
}
// Union returns RangeSet(A.keys | B.keys).
func (A *RangeSet) Union(B *RangeSet) *RangeSet {
// Union returns RangedKeySet(A.keys | B.keys).
func (A *RangedKeySet) Union(B *RangedKeySet) *RangedKeySet {
U := A.Clone()
U.UnionInplace(B)
return U
}
// Difference returns RangeSet(A.keys \ B.keys).
func (A *RangeSet) Difference(B *RangeSet) *RangeSet {
// Difference returns RangedKeySet(A.keys \ B.keys).
func (A *RangedKeySet) Difference(B *RangedKeySet) *RangedKeySet {
D := A.Clone()
D.DifferenceInplace(B)
return D
......@@ -282,7 +285,7 @@ func (A *RangeSet) Difference(B *RangeSet) *RangeSet {
// XXX Intersection
func (A *RangeSet) UnionInplace(B *RangeSet) {
func (A *RangedKeySet) UnionInplace(B *RangedKeySet) {
A.verify()
B.verify()
defer A.verify()
......@@ -293,7 +296,7 @@ func (A *RangeSet) UnionInplace(B *RangeSet) {
}
}
func (A *RangeSet) DifferenceInplace(B *RangeSet) {
func (A *RangedKeySet) DifferenceInplace(B *RangedKeySet) {
A.verify()
B.verify()
defer A.verify()
......@@ -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 ↑
func (S *RangeSet) verify() {
func (S *RangedKeySet) verify() {
// XXX !debug -> return ?
var badv []string
......@@ -344,19 +347,19 @@ func (S *RangeSet) verify() {
}
// Clone returns copy of the set.
func (orig *RangeSet) Clone() *RangeSet {
klon := &RangeSet{}
func (orig *RangedKeySet) Clone() *RangedKeySet {
klon := &RangedKeySet{}
klon.rangev = append(klon.rangev, orig.rangev...)
return klon
}
// Empty returns whether the set is empty.
func (S *RangeSet) Empty() bool {
func (S *RangedKeySet) Empty() bool {
return len(S.rangev) == 0
}
// 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) {
return false
}
......@@ -370,11 +373,11 @@ func (A *RangeSet) Equal(B *RangeSet) bool {
}
// Clear removes all elements from the set.
func (S *RangeSet) Clear() {
func (S *RangedKeySet) Clear() {
S.rangev = nil
}
func (S RangeSet) String() string {
func (S RangedKeySet) String() string {
s := "{"
for i, r := range S.rangev {
if i > 0 {
......@@ -386,7 +389,7 @@ func (S RangeSet) String() string {
return s
}
func (r Range) String() string {
func (r KeyRange) String() string {
slo := "-∞"; if r.lo > KeyMin { slo = fmt.Sprintf("%v", r.lo) }
shi := "∞"; if r.hi_ < KeyMax { shi = fmt.Sprintf("%v", r.hi_+1) }
return fmt.Sprintf("[%s,%s)", slo, shi)
......
......@@ -23,28 +23,28 @@ import (
"testing"
)
func TestRangeSet(t *testing.T) {
func TestRangedKeySet(t *testing.T) {
const (
oo = KeyMax
noo = KeyMin
)
type testEntry struct {
A, B *RangeSet
Union *RangeSet
Difference *RangeSet
A, B *RangedKeySet
Union *RangedKeySet
Difference *RangedKeySet
}
E := func(A, B, U, D *RangeSet) testEntry {
E := func(A, B, U, D *RangedKeySet) testEntry {
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 := func(kv ...Key) *RangeSet {
// S is shorthand to create RangedKeySet, e.g. S(1,2, 4,5) will return {[1,2) [4,5)}
S := func(kv ...Key) *RangedKeySet {
l := len(kv)
if l % 2 != 0 {
panic("odd number of keys")
}
S := &RangeSet{}
S := &RangedKeySet{}
for i := 0; i < l/2; i++ {
// construct .rangev directly, not via AddRange
lo := kv[2*i]
......@@ -53,7 +53,7 @@ func TestRangeSet(t *testing.T) {
if hi_ != oo {
hi_--
}
S.rangev = append(S.rangev, Range{lo, hi_})
S.rangev = append(S.rangev, KeyRange{lo, hi_})
}
S.verify()
return S
......@@ -145,7 +145,7 @@ func TestRangeSet(t *testing.T) {
}
// 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()
for _, r := range rangev {
has := S.HasRange(r)
......
......@@ -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.
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 ∞
lo, hi_ Key // [lo, hi_] NOTE _not_ hi) not to overflow at ∞ XXX -> Range
node Node
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)
Bv := rangeSplit{btop} // nodes expanded from B
// for phase 2:
Akqueue := &RangeSet{} // queue for keys in A to be processed for δ-
Bkqueue := &RangeSet{} // ----//---- in B for δ+
Akdone := &RangeSet{} // already processed keys in A
Bkdone := &RangeSet{} // ----//---- in B
Aktodo := func(k Key) {
Akqueue := &RangedKeySet{} // queue for keys in A to be processed for δ-
Bkqueue := &RangedKeySet{} // ----//---- in B for δ+
Akdone := &RangedKeySet{} // already processed keys in A
Bkdone := &RangedKeySet{} // ----//---- in B
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) {
tracef(" Akq <- %d\n", k)
Akqueue.Add(k)
}
*/
}
Bktodo := func(lo, hi_ Key) { // XXX -> func(r Range)
r := Range{lo, hi_}
Bktodo := func(r KeyRange) {
if !Bkdone.HasRange(r) {
δtodo := &RangeSet{}
δtodo := &RangedKeySet{}
δtodo.AddRange(r)
δtodo.DifferenceInplace(Bkdone)
tracef(" Bkq <- %s\n", δtodo)
......@@ -588,13 +596,13 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
}
*/
// Bkqueue <- ra.range
Bktodo(ra.lo, ra.hi_)
Bktodo(KeyRange{ra.lo, ra.hi_})
ra.done = true
case *Tree:
// empty tree - only queue holes covered by it
if len(a.Entryv()) == 0 {
Bktodo(ra.lo, ra.hi_)
Bktodo(KeyRange{ra.lo, ra.hi_})
/* XXX kill
for k := range holeIdx.GetInRange(ra.lo, ra.hi_) {
Bktodo(k)
......@@ -722,10 +730,15 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtrack.Add.AddPath(b.Path())
// Akqueue <- δB
br := KeyRange{b.lo, b.hi_}
Bkdone.AddRange(br)
Aktodo(br)
/*
for k_ := range δB {
Bkdone.Add(k_)
Aktodo(k_)
}
*/
b.done = true
}
......@@ -752,7 +765,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtrack.Del.AddPath(a.Path())
// Bkqueue <- a.range
Bktodo(a.lo, a.hi_)
Bktodo(KeyRange{a.lo, a.hi_})
/* XXX kill
// Bkqueue <- δ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