Commit cf3511fb authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 41045c0b
......@@ -37,6 +37,17 @@ func (r *KeyRange) Has(k Key) bool {
return (r.Lo <= k && k <= r.Hi_)
}
// Empty returns whether key range is empty.
func (r *KeyRange) Empty() bool {
hi := r.Hi_
if hi == KeyMax {
// [x,∞] cannot be empty because max x is ∞ and [∞,∞] has one element: ∞
return false
}
hi++ // no overflow
return r.Lo >= hi
}
func (r KeyRange) String() string {
var shi string
......
......@@ -25,8 +25,8 @@ import (
"sort"
)
const traceRangeMap = false
const debugRangeMap = false
const traceRangeMap = true
const debugRangeMap = true
// RangedMap is Key->VALUE map with adjacent keys mapped to the same value coalesced into Ranges.
//
......@@ -115,6 +115,10 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
M.verify()
defer M.verify()
if r.Empty() {
return // XXX or panic?
}
// clear range for r and insert new entry
// TODO optimize for same-value/set case (just merge all covered
// entries into one - - see commented AddRange from set vvv)
......@@ -367,7 +371,7 @@ func (M *RangedMap) verify() {
for _, bad := range badv {
emsg += fmt.Sprintf("- %s\n", bad)
}
emsg += fmt.Sprintf("\nS: %s\n", M)
emsg += fmt.Sprintf("\nM: %s\n", M)
panic(emsg)
}
}()
......
......@@ -38,14 +38,14 @@ const (
func TestRangedMap(t *testing.T) {
type testEntry struct {
A *RangedMap
B RangedMapEntry
Set *RangedMap // A.SetRange(B.keycov, B.value)
Del *RangedMap // A.DelRange(B.keycov)
Has bool // A.HasRange(B.keycov)
M *RangedMap
X RangedMapEntry
Set *RangedMap // M.SetRange(X.keycov, X.value)
Del *RangedMap // M.DelRange(X.keycov)
Has bool // M.HasRange(X.keycov)
}
E := func(A *RangedMap, B RangedMapEntry, S, D *RangedMap, H bool) testEntry {
return testEntry{A, B, S, D, H}
E := func(M *RangedMap, X RangedMapEntry, S, D *RangedMap, H bool) testEntry {
return testEntry{M, X, S, D, H}
}
// M is shorthand to create RangedMap, e.g. M(1,2,a, 3,4,b) will return {[1,2):a [3,4):b}.
......@@ -54,7 +54,7 @@ func TestRangedMap(t *testing.T) {
if l % 3 != 0 {
panic("non 3x number of arguments")
}
// askey converts arg to Key
// asKey converts arg to Key
asKey := func(arg interface{}) Key {
// go through reflect to accept all int, int64, Key, ...
return Key(reflect.ValueOf(arg).Int())
......@@ -78,8 +78,8 @@ func TestRangedMap(t *testing.T) {
return M
}
// K creates RangedMapEntry{v, [lo,hi)}
K := func(lo,hi Key, v string) RangedMapEntry {
// X creates RangedMapEntry{v, [lo,hi)}
X := func(lo,hi Key, v string) RangedMapEntry {
hi_ := hi
if hi_ != noo {
hi_--
......@@ -95,78 +95,142 @@ func TestRangedMap(t *testing.T) {
testv := []testEntry{
// empty vs empty
E(
M(1,2,a, 2,3,b), // A
K(1,3,x), // B
M(), // M
X(0,0,x), // X
M(), // Set
M(), // Del
n), // Has
// empty vs !empty
E(
M(), // M
X(1,2,x), // X
M(1,2,x), // Set
M(), // Del
n), // Has
// !empty vs empty
E(
M(1,2,a), // M
X(0,0,x), // X
M(1,2,a), // Set
M(1,2,a), // Del
y), // Has XXX ok
// basic change
E(
M(1,2,a), // M
X(1,2,x), // X
M(1,2,x), // Set
M(), // Del
y), // Has
// adjacent [1,3) [3,5)
E(
M(1,3,a), // M
X(3,5,x), // X
M(1,3,a, 3,5,x), // Set
M(1,3,a), // Del
n), // Has
// overlappin [1,3) [2,4)
E(
M(1,3,a), // M
X(2,4,x), // X
M(1,2,a, 2,4,x), // Set
M(1,2,a), // Del
n), // Has
// [1,7) vs [3,5) -> split
E(
M(1,7,a), // M
X(3,5,x), // X
M(1,3,a, 3,5,x, 5,7,a), // Set
M(1,3,a, 5,7,a), // Del
y), // Has
// several ranges vs [-∞,∞)
E(
M(1,3,a, 5,7,b, 8,9,c), // M
X(noo,oo,x), // X
M(noo,oo,x), // Set
M(), // Del
n), // Has
E(
M(1,2,a, 2,3,b), // M
X(1,3,x), // X
M(1,3,x), // Set
M(), // Del
y), // Has
// coalesce (same value, no overlap)
E(
M(1,2,a, 4,5,a), // A
K(2,4,a), // B
M(1,2,a, 4,5,a), // M
X(2,4,a), // X
M(1,5,a), // Set
M(1,2,a, 4,5,a), // Del
n), // Has
// coalesce (same value, overlap)
E(
M(1,4,a, 5,8,a), // A
K(2,6,a), // B
M(1,4,a, 5,8,a), // M
X(2,6,a), // X
M(1,8,a), // Set
M(1,2,a, 6,8,a), // Del
n), // Has
// - shrink left/right (value !same) + new entry
E(
M(1,4,a), // A
K(2,6,x), // B
M(1,4,a), // M
X(2,6,x), // X
M(1,2,a, 2,6,x), // Set
M(1,2,a), // Del
n), // Has
E(
M(5,8,b), // A
K(2,6,x), // B
M(5,8,b), // M
X(2,6,x), // X
M(2,6,x, 6,8,b), // Set
M( 6,8,b), // Del
n), // Has
E(
M(1,4,a, 5,8,b), // A
K(2,6,x), // B
M(1,4,a, 5,8,b), // M
X(2,6,x), // X
M(1,2,a, 2,6,x, 6,8,b), // Set
M(1,2,a, 6,8,b), // Del
n), // Has
}
for _, tt := range testv {
A := tt.A
B := tt.B
r := B.KeyRange
v := B.Value
M := tt.M
X := tt.X
r := X.KeyRange
v := X.Value
assertMapHasRange(t, A, r, tt.Has)
Aset := A.Clone()
Adel := A.Clone()
Aset.SetRange(r, v)
Adel.DelRange(r)
assertMapHasRange(t, M, r, tt.Has)
Mset := M.Clone()
Mdel := M.Clone()
Mset.SetRange(r, v)
Mdel.DelRange(r)
if !Aset.Equal(tt.Set) {
t.Errorf("SetRange:\n A: %s\n e: %s\n ->·: %s\n ok·: %s\n", A, B, Aset, tt.Set)
if !Mset.Equal(tt.Set) {
t.Errorf("SetRange:\n M: %s\n e: %s\n ->·: %s\n ok·: %s\n", M, X, Mset, tt.Set)
}
if !Adel.Equal(tt.Del) {
t.Errorf("DelRange:\n A: %s\n r: %s\n ->·: %s\n ok·: %s\n", A, r, Adel, tt.Del)
if !Mdel.Equal(tt.Del) {
t.Errorf("DelRange:\n M: %s\n r: %s\n ->·: %s\n ok·: %s\n", M, r, Mdel, tt.Del)
}
assertMapHasRange(t, Aset, r, true)
assertMapHasRange(t, Adel, r, false)
assertMapHasRange(t, Mset, r, true)
assertMapHasRange(t, Mdel, r, false)
verifyGet(t, A)
verifyGet(t, Aset)
verifyGet(t, Adel)
verifyGet(t, M)
verifyGet(t, Mset)
verifyGet(t, Mdel)
}
}
......@@ -187,8 +251,11 @@ func verifyGet(t *testing.T, M *RangedMap) {
Mranges = append(Mranges, M.AllRanges()...) // copy just in case it changes on Get
// verify "has-data"
Z := KeyRange{-100,+100} // models [-∞,∞)
for _, e := range Mranges {
for k := e.Lo; k <= e.Hi_; k++ {
lo := kmax(e.Lo, Z.Lo)
hi_ := kmin(e.Hi_, Z.Hi_)
for k := lo; k <= hi_; k++ {
v, ok := M.Get_(k)
if !(v == e.Value && ok) {
t.Errorf("%s\tGet(%s):\nhave: %q, %t\nwant: %q, true",
......@@ -200,13 +267,15 @@ func verifyGet(t *testing.T, M *RangedMap) {
// verify "no-data"
// NA = [-∞,∞) \ M
na := RangedKeySet{}
na.AddRange(KeyRange{-10,+10}) // models -∞,∞
na.AddRange(Z)
for _, e := range Mranges {
na.DelRange(e.KeyRange)
}
for _, r := range na.AllRanges() {
for k := r.Lo; k <= r.Hi_; k++ {
lo := kmax(r.Lo, Z.Lo)
hi_ := kmin(r.Hi_, Z.Hi_)
for k := lo; k <= hi_; k++ {
v, ok := M.Get_(k)
if !(v == "" && !ok) {
t.Errorf("%s\tGet(%s):\nhave: %q, %t\nwant: %q, false",
......@@ -215,3 +284,22 @@ func verifyGet(t *testing.T, M *RangedMap) {
}
}
}
// kmin returns min(a,b).
func kmin(a, b Key) Key {
if a < b {
return a
} else {
return b
}
}
// kmax returns max(a,b).
func kmax(a, b Key) Key {
if a > b {
return a
} else {
return b
}
}
......@@ -110,7 +110,7 @@ func TestRangedKeySet(t *testing.T) {
S(1,7),
S(1,3, 5,7)),
// several ranges \ [-∞, ∞) -> ø
// several ranges \ [-∞,∞) -> ø
E(
S(1,3, 5,7, 11,100), // A
S(noo, oo), // B
......
......@@ -27,8 +27,8 @@ import (
"sort"
)
const trace_RangedMap_str = false
const debug_RangedMap_str = false
const trace_RangedMap_str = true
const debug_RangedMap_str = true
// _RangedMap_str is Key->string map with adjacent keys mapped to the same value coalesced into Ranges.
//
......@@ -117,6 +117,10 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
M.verify()
defer M.verify()
if r.Empty() {
return // XXX or panic?
}
// clear range for r and insert new entry
// TODO optimize for same-value/set case (just merge all covered
// entries into one - - see commented AddRange from set vvv)
......@@ -369,7 +373,7 @@ func (M *_RangedMap_str) verify() {
for _, bad := range badv {
emsg += fmt.Sprintf("- %s\n", bad)
}
emsg += fmt.Sprintf("\nS: %s\n", M)
emsg += fmt.Sprintf("\nM: %s\n", M)
panic(emsg)
}
}()
......
......@@ -27,8 +27,8 @@ import (
"sort"
)
const trace_RangedMap_void = false
const debug_RangedMap_void = false
const trace_RangedMap_void = true
const debug_RangedMap_void = true
// _RangedMap_void is Key->void map with adjacent keys mapped to the same value coalesced into Ranges.
//
......@@ -117,6 +117,10 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
M.verify()
defer M.verify()
if r.Empty() {
return // XXX or panic?
}
// clear range for r and insert new entry
// TODO optimize for same-value/set case (just merge all covered
// entries into one - - see commented AddRange from set vvv)
......@@ -369,7 +373,7 @@ func (M *_RangedMap_void) verify() {
for _, bad := range badv {
emsg += fmt.Sprintf("- %s\n", bad)
}
emsg += fmt.Sprintf("\nS: %s\n", M)
emsg += fmt.Sprintf("\nM: %s\n", M)
panic(emsg)
}
}()
......
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