Commit 6972f999 authored by Kirill Smelkov's avatar Kirill Smelkov

X xbtree/blib: RangedMap, RangedSet += IntersectsRange, Intersection

IntersectsRange is needed for one assert in concurrenct ΔBtail rebuild.
parent c4366b14
...@@ -359,6 +359,40 @@ func (M *RangedMap) HasRange(r KeyRange) (yes bool) { ...@@ -359,6 +359,40 @@ func (M *RangedMap) HasRange(r KeyRange) (yes bool) {
} }
} }
// IntersectsRange returns whether some keys from range r belong to the map.
func (M *RangedMap) IntersectsRange(r KeyRange) (yes bool) {
if traceRangeMap {
fmt.Printf("\n\nIntersectsRange:\n")
fmt.Printf(" M: %s\n", M)
fmt.Printf(" r: %s\n", r)
defer func() {
fmt.Printf("->·: %v\n", yes)
}()
}
M.verify()
if r.Empty() {
return false
}
// find first ilo: r.lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <= M.entryv[i].Hi_
})
debugfRMap("\tilo: %d\n", ilo)
if ilo == l { // not found
return false
}
// [ilo].hi may be either inside r (≤ r.hi), or > r.hi
// - if it is inside -> overlap is there,
// - if it is > r.hi -> overlap is there if [ilo].lo < r.hi
// => in any case overlap is there if [ilo].lo < r.hi
return M.entryv[ilo].Lo <= r.Hi_
}
// -------- // --------
......
...@@ -38,14 +38,15 @@ const ( ...@@ -38,14 +38,15 @@ const (
func TestRangedMap(t *testing.T) { func TestRangedMap(t *testing.T) {
type testEntry struct { type testEntry struct {
M *RangedMap M *RangedMap
X RangedMapEntry X RangedMapEntry
Set *RangedMap // M.SetRange(X.keycov, X.value) Set *RangedMap // M.SetRange(X.keycov, X.value)
Del *RangedMap // M.DelRange(X.keycov) Del *RangedMap // M.DelRange(X.keycov)
Has bool // M.HasRange(X.keycov) Has bool // M.HasRange(X.keycov)
Intersects bool // M.IntersectsRange(X.Keycov)
} }
E := func(M *RangedMap, X RangedMapEntry, S, D *RangedMap, H bool) testEntry { E := func(M *RangedMap, X RangedMapEntry, S, D *RangedMap, H, I bool) testEntry {
return testEntry{M, X, S, D, H} return testEntry{M, X, S, D, H, I}
} }
// M is shorthand to create RangedMap, e.g. M(1,2,a, 3,4,b) will return {[1,2):a [3,4):b}. // M is shorthand to create RangedMap, e.g. M(1,2,a, 3,4,b) will return {[1,2):a [3,4):b}.
...@@ -101,7 +102,8 @@ func TestRangedMap(t *testing.T) { ...@@ -101,7 +102,8 @@ func TestRangedMap(t *testing.T) {
X(0,0,x), // X X(0,0,x), // X
M(), // Set M(), // Set
M(), // Del M(), // Del
y), // Has y, // Has
n), // Intersects
// empty vs !empty // empty vs !empty
E( E(
...@@ -109,7 +111,8 @@ func TestRangedMap(t *testing.T) { ...@@ -109,7 +111,8 @@ func TestRangedMap(t *testing.T) {
X(1,2,x), // X X(1,2,x), // X
M(1,2,x), // Set M(1,2,x), // Set
M(), // Del M(), // Del
n), // Has n, // Has
n), // Intersects
// !empty vs empty // !empty vs empty
E( E(
...@@ -117,7 +120,8 @@ func TestRangedMap(t *testing.T) { ...@@ -117,7 +120,8 @@ func TestRangedMap(t *testing.T) {
X(0,0,x), // X X(0,0,x), // X
M(1,2,a), // Set M(1,2,a), // Set
M(1,2,a), // Del M(1,2,a), // Del
y), // Has y, // Has
n), // Intersects
// basic change // basic change
E( E(
...@@ -125,7 +129,8 @@ func TestRangedMap(t *testing.T) { ...@@ -125,7 +129,8 @@ func TestRangedMap(t *testing.T) {
X(1,2,x), // X X(1,2,x), // X
M(1,2,x), // Set M(1,2,x), // Set
M(), // Del M(), // Del
y), // Has y, // Has
y), // Intersects
// adjacent [1,3) [3,5) // adjacent [1,3) [3,5)
E( E(
...@@ -133,7 +138,8 @@ func TestRangedMap(t *testing.T) { ...@@ -133,7 +138,8 @@ func TestRangedMap(t *testing.T) {
X(3,5,x), // X X(3,5,x), // X
M(1,3,a, 3,5,x), // Set M(1,3,a, 3,5,x), // Set
M(1,3,a), // Del M(1,3,a), // Del
n), // Has n, // Has
n), // Intersects
// overlapping [1,3) [2,4) // overlapping [1,3) [2,4)
E( E(
...@@ -141,7 +147,8 @@ func TestRangedMap(t *testing.T) { ...@@ -141,7 +147,8 @@ func TestRangedMap(t *testing.T) {
X(2,4,x), // X X(2,4,x), // X
M(1,2,a, 2,4,x), // Set M(1,2,a, 2,4,x), // Set
M(1,2,a), // Del M(1,2,a), // Del
n), // Has n, // Has
y), // Intersects
// [1,7) vs [3,5) -> split // [1,7) vs [3,5) -> split
E( E(
...@@ -149,7 +156,8 @@ func TestRangedMap(t *testing.T) { ...@@ -149,7 +156,8 @@ func TestRangedMap(t *testing.T) {
X(3,5,x), // X X(3,5,x), // X
M(1,3,a, 3,5,x, 5,7,a), // Set M(1,3,a, 3,5,x, 5,7,a), // Set
M(1,3,a, 5,7,a), // Del M(1,3,a, 5,7,a), // Del
y), // Has y, // Has
y), // Intersects
// several ranges vs [-∞,∞) // several ranges vs [-∞,∞)
E( E(
...@@ -157,14 +165,16 @@ func TestRangedMap(t *testing.T) { ...@@ -157,14 +165,16 @@ func TestRangedMap(t *testing.T) {
X(noo,oo,x), // X X(noo,oo,x), // X
M(noo,oo,x), // Set M(noo,oo,x), // Set
M(), // Del M(), // Del
n), // Has n, // Has
y), // Intersects
E( E(
M(1,2,a, 2,3,b), // M M(1,2,a, 2,3,b), // M
X(1,3,x), // X X(1,3,x), // X
M(1,3,x), // Set M(1,3,x), // Set
M(), // Del M(), // Del
y), // Has y, // Has
y), // Intersects
// coalesce (same value, no overlap) // coalesce (same value, no overlap)
E( E(
...@@ -172,7 +182,8 @@ func TestRangedMap(t *testing.T) { ...@@ -172,7 +182,8 @@ func TestRangedMap(t *testing.T) {
X(2,4,a), // X X(2,4,a), // X
M(1,5,a), // Set M(1,5,a), // Set
M(1,2,a, 4,5,a), // Del M(1,2,a, 4,5,a), // Del
n), // Has n, // Has
n), // Intersects
// coalesce (same value, overlap) // coalesce (same value, overlap)
E( E(
...@@ -180,7 +191,8 @@ func TestRangedMap(t *testing.T) { ...@@ -180,7 +191,8 @@ func TestRangedMap(t *testing.T) {
X(2,6,a), // X X(2,6,a), // X
M(1,8,a), // Set M(1,8,a), // Set
M(1,2,a, 6,8,a), // Del M(1,2,a, 6,8,a), // Del
n), // Has n, // Has
y), // Intersects
// - shrink left/right (value !same) + new entry // - shrink left/right (value !same) + new entry
E( E(
...@@ -188,19 +200,22 @@ func TestRangedMap(t *testing.T) { ...@@ -188,19 +200,22 @@ func TestRangedMap(t *testing.T) {
X(2,6,x), // X X(2,6,x), // X
M(1,2,a, 2,6,x), // Set M(1,2,a, 2,6,x), // Set
M(1,2,a), // Del M(1,2,a), // Del
n), // Has n, // Has
y), // Intersects
E( E(
M(5,8,b), // M M(5,8,b), // M
X(2,6,x), // X X(2,6,x), // X
M(2,6,x, 6,8,b), // Set M(2,6,x, 6,8,b), // Set
M( 6,8,b), // Del M( 6,8,b), // Del
n), // Has n, // Has
y), // Intersects
E( E(
M(1,4,a, 5,8,b), // M M(1,4,a, 5,8,b), // M
X(2,6,x), // X X(2,6,x), // X
M(1,2,a, 2,6,x, 6,8,b), // Set M(1,2,a, 2,6,x, 6,8,b), // Set
M(1,2,a, 6,8,b), // Del M(1,2,a, 6,8,b), // Del
n), // Has n, // Has
y), // Intersects
} }
for _, tt := range testv { for _, tt := range testv {
...@@ -210,6 +225,7 @@ func TestRangedMap(t *testing.T) { ...@@ -210,6 +225,7 @@ func TestRangedMap(t *testing.T) {
v := X.Value v := X.Value
assertMapHasRange(t, M, r, tt.Has) assertMapHasRange(t, M, r, tt.Has)
assertMapIntersectsRange(t, M, r, tt.Intersects)
Mset := M.Clone() Mset := M.Clone()
Mdel := M.Clone() Mdel := M.Clone()
Mset.SetRange(r, v) Mset.SetRange(r, v)
...@@ -226,11 +242,9 @@ func TestRangedMap(t *testing.T) { ...@@ -226,11 +242,9 @@ func TestRangedMap(t *testing.T) {
} }
assertMapHasRange(t, Mset, r, true) assertMapHasRange(t, Mset, r, true)
rInMdel := false assertMapHasRange(t, Mdel, r, r.Empty())
if r.Empty() { assertMapIntersectsRange(t, Mset, r, !r.Empty())
rInMdel = true assertMapIntersectsRange(t, Mdel, r, false)
}
assertMapHasRange(t, Mdel, r, rInMdel)
verifyGet(t, M) verifyGet(t, M)
verifyGet(t, Mset) verifyGet(t, Mset)
...@@ -238,7 +252,7 @@ func TestRangedMap(t *testing.T) { ...@@ -238,7 +252,7 @@ func TestRangedMap(t *testing.T) {
} }
} }
// assertMapHasRange asserts that RangeMap M.HasRange(r) == hasOK. // assertMapHasRange asserts that RangedMap M.HasRange(r) == hasOK.
func assertMapHasRange(t *testing.T, M *RangedMap, r KeyRange, hasOK bool) { func assertMapHasRange(t *testing.T, M *RangedMap, r KeyRange, hasOK bool) {
t.Helper() t.Helper()
has := M.HasRange(r) has := M.HasRange(r)
...@@ -247,6 +261,15 @@ func assertMapHasRange(t *testing.T, M *RangedMap, r KeyRange, hasOK bool) { ...@@ -247,6 +261,15 @@ func assertMapHasRange(t *testing.T, M *RangedMap, r KeyRange, hasOK bool) {
} }
} }
// assertMapIntersectsRange asserts that RangedMap M.IntersectsRange(r) == intersectsOK.
func assertMapIntersectsRange(t *testing.T, M *RangedMap, r KeyRange, intersectsOK bool) {
t.Helper()
intersects := M.IntersectsRange(r)
if !(intersects == intersectsOK) {
t.Errorf("IntersectsRange:\n M: %s\n r: %s\n ->·: %t\n ok·: %t\n", M, r, intersects, intersectsOK)
}
}
// verifyGet verifies RangedMap.Get . // verifyGet verifies RangedMap.Get .
func verifyGet(t *testing.T, M *RangedMap) { func verifyGet(t *testing.T, M *RangedMap) {
t.Helper() t.Helper()
......
...@@ -63,10 +63,15 @@ func (S *RangedKeySet) DelRange(r KeyRange) { ...@@ -63,10 +63,15 @@ func (S *RangedKeySet) DelRange(r KeyRange) {
} }
// 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 *RangedKeySet) HasRange(r KeyRange) (yes bool) { func (S *RangedKeySet) HasRange(r KeyRange) bool {
return S.m.HasRange(r) return S.m.HasRange(r)
} }
// IntersectsRange returns whether some keys from range r belong to the set.
func (S *RangedKeySet) IntersectsRange(r KeyRange) bool {
return S.m.IntersectsRange(r)
}
// Union returns RangedKeySet(A.keys | B.keys). // Union returns RangedKeySet(A.keys | B.keys).
func (A *RangedKeySet) Union(B *RangedKeySet) *RangedKeySet { func (A *RangedKeySet) Union(B *RangedKeySet) *RangedKeySet {
...@@ -82,7 +87,12 @@ func (A *RangedKeySet) Difference(B *RangedKeySet) *RangedKeySet { ...@@ -82,7 +87,12 @@ func (A *RangedKeySet) Difference(B *RangedKeySet) *RangedKeySet {
return D return D
} }
// TODO Intersection // Intersection returns RangedKeySet(A.keys ^ B.keys).
func (A *RangedKeySet) Intersection(B *RangedKeySet) *RangedKeySet {
I := A.Clone()
I.IntersectionInplace(B)
return I
}
func (A *RangedKeySet) UnionInplace(B *RangedKeySet) { func (A *RangedKeySet) UnionInplace(B *RangedKeySet) {
A.verify() A.verify()
...@@ -109,6 +119,21 @@ func (A *RangedKeySet) DifferenceInplace(B *RangedKeySet) { ...@@ -109,6 +119,21 @@ func (A *RangedKeySet) DifferenceInplace(B *RangedKeySet) {
} }
} }
func (A *RangedKeySet) IntersectionInplace(B *RangedKeySet) {
A.verify()
B.verify()
defer A.verify()
// XXX very dumb
// A^B = (A∪B) \ (A\B ∪ B\A)
AdB := A.Difference(B)
BdA := B.Difference(A)
ddd := AdB
ddd.UnionInplace(BdA)
A.UnionInplace(B)
A.DifferenceInplace(ddd)
}
// -------- // --------
...@@ -152,6 +177,6 @@ func (S *RangedKeySet) AllRanges() /*readonly*/[]KeyRange { ...@@ -152,6 +177,6 @@ func (S *RangedKeySet) AllRanges() /*readonly*/[]KeyRange {
} }
func (S RangedKeySet) String() string { func (S RangedKeySet) String() string {
// RangeMap<void> supports formatting for set out of the box // RangedMap<void> supports formatting for set out of the box
return S.m.String() return S.m.String()
} }
...@@ -44,12 +44,13 @@ func TestRangedKeySetTypes(t *testing.T) { ...@@ -44,12 +44,13 @@ func TestRangedKeySetTypes(t *testing.T) {
func TestRangedKeySet(t *testing.T) { func TestRangedKeySet(t *testing.T) {
type testEntry struct { type testEntry struct {
A, B *RangedKeySet A, B *RangedKeySet
Union *RangedKeySet Union *RangedKeySet
Difference *RangedKeySet Difference *RangedKeySet
Intersection *RangedKeySet
} }
E := func(A, B, U, D *RangedKeySet) testEntry { E := func(A, B, U, D, I *RangedKeySet) testEntry {
return testEntry{A, B, U, D} return testEntry{A, B, U, D, I}
} }
// S is shorthand to create RangedKeySet, 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)}
...@@ -81,68 +82,78 @@ func TestRangedKeySet(t *testing.T) { ...@@ -81,68 +82,78 @@ func TestRangedKeySet(t *testing.T) {
S(), // A S(), // A
S(), // B S(), // B
S(), // U S(), // U
S()), // D S(), // D
S()), // I
E( E(
S(), // A S(), // A
S(1,2), // B S(1,2), // B
S(1,2), // U S(1,2), // U
S()), // D S(), // D
S()), // I
E( E(
S(1,2), // A S(1,2), // A
S(), // B S(), // B
S(1,2), // U S(1,2), // U
S(1,2)),// D S(1,2), // D
S()), // I
E( E(
S(1,2), // A S(1,2), // A
S(1,2), // B S(1,2), // B
S(1,2), // U S(1,2), // U
S()), // D S(), // D
S(1,2)),// I
// adjacent [1,3) [3,5) // adjacent [1,3) [3,5)
E( E(
S(1,3), // A S(1,3), // A
S(3,5), // B S(3,5), // B
S(1,5), // U S(1,5), // U
S(1,3)), // D S(1,3), // D
S()), // I
// overlapping [1,3) [2,4) // overlapping [1,3) [2,4)
E( E(
S(1,3), // A S(1,3), // A
S(2,4), // B S(2,4), // B
S(1,4), // U S(1,4), // U
S(1,2)), // D S(1,2), // D
S(2,3)),// I
// [1,7) \ [3,5) -> [1,3) [5,7) // [1,7) \ [3,5) -> [1,3) [5,7)
E( E(
S(1,7), // A S(1,7), // A
S(3,5), // B S(3,5), // B
S(1,7), S(1,7), // U
S(1,3, 5,7)), S(1,3, 5,7), // D
S(3,5)), // I
// several ranges \ [-∞,∞) -> ø // several ranges \ [-∞,∞) -> ø
E( E(
S(1,3, 5,7, 11,100), // A S(1,3, 5,7, 11,100), // A
S(noo, oo), // B S(noo, oo), // B
S(noo, oo), // U S(noo, oo), // U
S()), // D S(), // D
S(1,3, 5,7, 11,100)), // I
// [1,3) [5,7) + insert [3,5) -> [1,7) // [1,3) [5,7) + insert [3,5) -> [1,7)
E( E(
S(1,3, 5,7), // A S(1,3, 5,7), // A
S(3,5), // B S(3,5), // B
S(1,7), // U S(1,7), // U
S(1,3, 5,7)), // D S(1,3, 5,7), // D
S()), // I
// delete covering several ranges // delete covering several ranges
// [-1,0) [1,3) [5,7) [9,11) [15,20) [100,200) \ [2,17) // [-1,0) [1,3) [5,7) [9,11) [15,20) [100,200) \ [2,17)
E( E(
S(-1,0, 1,3, 5,7, 9,11, 15,20, 100,200), // A S(-1,0, 1,3, 5,7, 9,11, 15,20, 100,200),// A
S(2,17), // B S(2,17), // B
S(-1,0, 1,20, 100,200), // U S(-1,0, 1,20, 100,200), // U
S(-1,0, 1,2, 17,20, 100,200)), // D S(-1,0, 1,2, 17,20, 100,200), // D
S(2,3, 5,7, 9,11, 15,17)), // I
} }
for _, tt := range testv { for _, tt := range testv {
...@@ -150,6 +161,7 @@ func TestRangedKeySet(t *testing.T) { ...@@ -150,6 +161,7 @@ func TestRangedKeySet(t *testing.T) {
B := tt.B B := tt.B
U := A.Union(B) U := A.Union(B)
D := A.Difference(B) D := A.Difference(B)
I := A.Intersection(B)
if !U.Equal(tt.Union) { if !U.Equal(tt.Union) {
t.Errorf("Union:\n A: %s\n B: %s\n ->u: %s\n okU: %s\n", A, B, U, tt.Union) t.Errorf("Union:\n A: %s\n B: %s\n ->u: %s\n okU: %s\n", A, B, U, tt.Union)
...@@ -157,12 +169,18 @@ func TestRangedKeySet(t *testing.T) { ...@@ -157,12 +169,18 @@ func TestRangedKeySet(t *testing.T) {
if !D.Equal(tt.Difference) { if !D.Equal(tt.Difference) {
t.Errorf("Difference:\n A: %s\n B: %s\n ->d: %s\n okD: %s\n", A, B, D, tt.Difference) t.Errorf("Difference:\n A: %s\n B: %s\n ->d: %s\n okD: %s\n", A, B, D, tt.Difference)
} }
if !I.Equal(tt.Intersection) {
t.Errorf("Intersection:\n A: %s\n B: %s\n ->i: %s\n okI: %s\n", A, B, I, tt.Intersection)
}
// HasRange // HasRange
assertSetHasRanges(t, A, A.AllRanges(), true) assertSetHasRanges(t, A, A.AllRanges(), true)
assertSetHasRanges(t, B, B.AllRanges(), true) assertSetHasRanges(t, B, B.AllRanges(), true)
assertSetHasRanges(t, U, A.AllRanges(), true) assertSetHasRanges(t, U, A.AllRanges(), true)
assertSetHasRanges(t, U, B.AllRanges(), true) assertSetHasRanges(t, U, B.AllRanges(), true)
assertSetHasRanges(t, A, I.AllRanges(), true)
assertSetHasRanges(t, B, I.AllRanges(), true)
assertSetHasRanges(t, U, I.AllRanges(), true)
Dab := D Dab := D
Dba := B.Difference(A) Dba := B.Difference(A)
...@@ -170,6 +188,20 @@ func TestRangedKeySet(t *testing.T) { ...@@ -170,6 +188,20 @@ func TestRangedKeySet(t *testing.T) {
assertSetHasRanges(t, B, Dab.AllRanges(), false) assertSetHasRanges(t, B, Dab.AllRanges(), false)
assertSetHasRanges(t, B, Dba.AllRanges(), true) assertSetHasRanges(t, B, Dba.AllRanges(), true)
assertSetHasRanges(t, A, Dba.AllRanges(), false) assertSetHasRanges(t, A, Dba.AllRanges(), false)
assertSetHasRanges(t, Dab, I.AllRanges(), false)
assertSetHasRanges(t, Dba, I.AllRanges(), false)
assertSetHasRanges(t, I, Dab.AllRanges(), false)
assertSetHasRanges(t, I, Dba.AllRanges(), false)
// IntersectsRange (= (A^B)!=ø)
assertSetIntersectsRanges(t, A, I.AllRanges(), !I.Empty())
assertSetIntersectsRanges(t, B, I.AllRanges(), !I.Empty())
assertSetIntersectsRanges(t, Dab, B.AllRanges(), false)
assertSetIntersectsRanges(t, Dba, A.AllRanges(), false)
assertSetIntersectsRanges(t, Dab, I.AllRanges(), false)
assertSetIntersectsRanges(t, Dba, I.AllRanges(), false)
assertSetIntersectsRanges(t, I, Dab.AllRanges(), false)
assertSetIntersectsRanges(t, I, Dba.AllRanges(), false)
} }
} }
...@@ -183,3 +215,14 @@ func assertSetHasRanges(t *testing.T, S *RangedKeySet, rangev []KeyRange, hasOK ...@@ -183,3 +215,14 @@ func assertSetHasRanges(t *testing.T, S *RangedKeySet, rangev []KeyRange, hasOK
} }
} }
} }
// assertSetIntersectsRanges asserts for all ranges from rangev that RangedSet S.IntersectsRange(r) == intersectsOK.
func assertSetIntersectsRanges(t *testing.T, S *RangedKeySet, rangev []KeyRange, intersectsOK bool) {
t.Helper()
for _, r := range rangev {
intersects := S.IntersectsRange(r)
if intersects != intersectsOK {
t.Errorf("IntersectsRange:\n S: %s\n r: %s\n ->: %v\n ok: %v\n", S, r, intersects, intersectsOK)
}
}
}
...@@ -361,6 +361,40 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) { ...@@ -361,6 +361,40 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
} }
} }
// IntersectsRange returns whether some keys from range r belong to the map.
func (M *_RangedMap_str) IntersectsRange(r KeyRange) (yes bool) {
if trace_RangedMap_str {
fmt.Printf("\n\nIntersectsRange:\n")
fmt.Printf(" M: %s\n", M)
fmt.Printf(" r: %s\n", r)
defer func() {
fmt.Printf("->·: %v\n", yes)
}()
}
M.verify()
if r.Empty() {
return false
}
// find first ilo: r.lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <= M.entryv[i].Hi_
})
debugf_RangedMap_str("\tilo: %d\n", ilo)
if ilo == l { // not found
return false
}
// [ilo].hi may be either inside r (≤ r.hi), or > r.hi
// - if it is inside -> overlap is there,
// - if it is > r.hi -> overlap is there if [ilo].lo < r.hi
// => in any case overlap is there if [ilo].lo < r.hi
return M.entryv[ilo].Lo <= r.Hi_
}
// -------- // --------
......
...@@ -361,6 +361,40 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) { ...@@ -361,6 +361,40 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
} }
} }
// IntersectsRange returns whether some keys from range r belong to the map.
func (M *_RangedMap_void) IntersectsRange(r KeyRange) (yes bool) {
if trace_RangedMap_void {
fmt.Printf("\n\nIntersectsRange:\n")
fmt.Printf(" M: %s\n", M)
fmt.Printf(" r: %s\n", r)
defer func() {
fmt.Printf("->·: %v\n", yes)
}()
}
M.verify()
if r.Empty() {
return false
}
// find first ilo: r.lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <= M.entryv[i].Hi_
})
debugf_RangedMap_void("\tilo: %d\n", ilo)
if ilo == l { // not found
return false
}
// [ilo].hi may be either inside r (≤ r.hi), or > r.hi
// - if it is inside -> overlap is there,
// - if it is > r.hi -> overlap is there if [ilo].lo < r.hi
// => in any case overlap is there if [ilo].lo < r.hi
return M.entryv[ilo].Lo <= r.Hi_
}
// -------- // --------
......
...@@ -364,6 +364,40 @@ func (M *_RangedMap_RebuildJob) HasRange(r blib.KeyRange) (yes bool) { ...@@ -364,6 +364,40 @@ func (M *_RangedMap_RebuildJob) HasRange(r blib.KeyRange) (yes bool) {
} }
} }
// IntersectsRange returns whether some keys from range r belong to the map.
func (M *_RangedMap_RebuildJob) IntersectsRange(r blib.KeyRange) (yes bool) {
if trace_RangedMap_RebuildJob {
fmt.Printf("\n\nIntersectsRange:\n")
fmt.Printf(" M: %s\n", M)
fmt.Printf(" r: %s\n", r)
defer func() {
fmt.Printf("->·: %v\n", yes)
}()
}
M.verify()
if r.Empty() {
return false
}
// find first ilo: r.lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
return r.Lo <= M.entryv[i].Hi_
})
debugf_RangedMap_RebuildJob("\tilo: %d\n", ilo)
if ilo == l { // not found
return false
}
// [ilo].hi may be either inside r (≤ r.hi), or > r.hi
// - if it is inside -> overlap is there,
// - if it is > r.hi -> overlap is there if [ilo].lo < r.hi
// => in any case overlap is there if [ilo].lo < r.hi
return M.entryv[ilo].Lo <= r.Hi_
}
// -------- // --------
......
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