Commit a5b9b19b authored by Kirill Smelkov's avatar Kirill Smelkov

X SetRange draftly works

parent ae51741d
......@@ -115,6 +115,36 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
M.verify()
defer M.verify()
// clear range for r and insert new entry
// TODO optimize for set case (just merge all covered entries into one)
i := M.delRange(r)
vInsert(&M.entryv, i, e)
debugfRMap("\tinsert %s\t-> %s\n", e, M)
// check if we should merge inserted entry with right/left neighbours
if i+1 < len(M.entryv) { // right
x := M.entryv[i]
right := M.entryv[i+1]
if (x.Hi_+1 == right.Lo) && (v == right.Value) {
vReplaceSlice(&M.entryv, i,i+2,
RangedMapEntry{v, KeyRange{x.Lo, right.Hi_}})
debugfRMap("\tmerge right\t-> %s\n", M)
}
}
if i > 0 { // left
left := M.entryv[i-1]
x := M.entryv[i]
if (left.Hi_+1 == x.Lo) && (left.Value == v) {
vReplaceSlice(&M.entryv, i-1,i+1,
RangedMapEntry{v, KeyRange{left.Lo, x.Hi_}})
debugfRMap("\tmerge left\t-> %s\n", M)
}
}
// done
/*
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -141,6 +171,45 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
}
debugfRMap("\tjhi: %d\n", jhi)
// [ilo+1:jhi-1] should be deleted
if (jhi - ilo) > 2 {
vDeleteSlice(&M.entryv, ilo+1,jhi-1)
debugfRMap("\tdelete M[%d:%d]\t-> %s\n", ilo+1, jhi-1, M)
}
// if r was overlapping with sole region -> presplit it TODO only if !vsame
x := M.entryv[ilo]
if jhi-ilo == 1 && x.Lo < r.Lo && r.Hi_ < x.Hi_ {
vInsert(&M.entryv, ilo, x)
jhi++
debugfRMap("\tpresplit copy %s\t-> %s\n", x, M)
}
jhi = -1 // no longer valid
// create new entry
// now it is
vInsert(&M.entryv, ilo+1, e)
// [ilo] is now to the left
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - XXX
if jhi-ilo == 1 {
x := M.entryv[ilo]
if x.Value != v {
vInsert(&M.entryv, ilo, x)
jhi++
debugfRMap("\tpresplit copy %s\t-> %s\n", x, M)
} else {
// XXX extend left/right if needed XXX here?
}
}
if xl.Value != v {
}
// entries in [ilo:jhi) [r.Lo,r.hi) and should be merged into one
// FIXME check different values
if (jhi - ilo) > 1 {
......@@ -190,6 +259,7 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
}
// done
*/
}
// DelRange removes range r from the map.
......@@ -204,6 +274,12 @@ func (M *RangedMap) DelRange(r KeyRange) {
M.verify()
defer M.verify()
M.delRange(r)
}
// delRange deletes range r from the map and returns .entryv index where r
// should be inserted/appended if needed.
func (M *RangedMap) delRange(r KeyRange) (i int) {
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -213,7 +289,7 @@ func (M *RangedMap) DelRange(r KeyRange) {
if ilo == l { // not found
debugfRMap("\tnon-overlap right\n")
return
return l
}
// find last jhi: [jhi].Lo < r.hi
......@@ -231,9 +307,11 @@ func (M *RangedMap) DelRange(r KeyRange) {
if jhi == 0 {
debugfRMap("\tnon-overlap left\n")
return
return 0
}
// XXX if jhi - ilo == 0 { return "non-overlap" } ?
// [ilo+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked,
// or split+shrinked if ilo==jhi-1 and r is inside [ilo]
......@@ -260,6 +338,7 @@ func (M *RangedMap) DelRange(r KeyRange) {
}
// done
return ilo
}
// HasRange returns whether all keys from range r belong to the map.
......@@ -286,7 +365,6 @@ func (M *RangedMap) HasRange(r KeyRange) (yes bool) {
return false
}
// scan right and verify that whole r is covered
lo := r.Lo
for {
......
......@@ -34,15 +34,15 @@ func TestRangedMap(t *testing.T) {
A *RangedMap
B RangedMapEntry
Set *RangedMap // A.SetRange(B.keycov, B.value)
Del *RangedMap // A.DelRange(B)
Has bool // A.HasRange(B)
Del *RangedMap // A.DelRange(B.keycov)
Has bool // A.HasRange(B.keycov)
// XXX Get?
}
E := func(A *RangedMap, B RangedMapEntry, S, D *RangedMap, H bool) testEntry {
return testEntry{A, B, 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"}.
// M is shorthand to create RangedMap, e.g. M(1,2,a, 3,4,b) will return {[1,2):a [3,4):b}.
M := func(argv ...interface{}) *RangedMap {
l := len(argv)
if l % 3 != 0 {
......
......@@ -122,6 +122,12 @@ func TestRangedKeySet(t *testing.T) {
S(noo, oo), // U
S()), // D
E(
S(5,7), // A
S(3,5), // B
S(3,7), // U
S(5,7)), // D
// [1,3) [5,7) + insert [3,5) -> [1,7)
E(
S(1,3, 5,7), // A
......
......@@ -117,6 +117,36 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
M.verify()
defer M.verify()
// clear range for r and insert new entry
// TODO optimize for set case (just merge all covered entries into one)
i := M.delRange(r)
vInsert__RangedMap_str(&M.entryv, i, e)
debugf_RangedMap_str("\tinsert %s\t-> %s\n", e, M)
// check if we should merge inserted entry with right/left neighbours
if i+1 < len(M.entryv) { // right
x := M.entryv[i]
right := M.entryv[i+1]
if (x.Hi_+1 == right.Lo) && (v == right.Value) {
vReplaceSlice__RangedMap_str(&M.entryv, i,i+2,
_RangedMap_strEntry{v, KeyRange{x.Lo, right.Hi_}})
debugf_RangedMap_str("\tmerge right\t-> %s\n", M)
}
}
if i > 0 { // left
left := M.entryv[i-1]
x := M.entryv[i]
if (left.Hi_+1 == x.Lo) && (left.Value == v) {
vReplaceSlice__RangedMap_str(&M.entryv, i-1,i+1,
_RangedMap_strEntry{v, KeyRange{left.Lo, x.Hi_}})
debugf_RangedMap_str("\tmerge left\t-> %s\n", M)
}
}
// done
/*
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -143,6 +173,45 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
}
debugf_RangedMap_str("\tjhi: %d\n", jhi)
// [ilo+1:jhi-1] should be deleted
if (jhi - ilo) > 2 {
vDeleteSlice__RangedMap_str(&M.entryv, ilo+1,jhi-1)
debugf_RangedMap_str("\tdelete M[%d:%d]\t-> %s\n", ilo+1, jhi-1, M)
}
// if r was overlapping with sole region -> presplit it TODO only if !vsame
x := M.entryv[ilo]
if jhi-ilo == 1 && x.Lo < r.Lo && r.Hi_ < x.Hi_ {
vInsert__RangedMap_str(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_str("\tpresplit copy %s\t-> %s\n", x, M)
}
jhi = -1 // no longer valid
// create new entry
// now it is
vInsert__RangedMap_str(&M.entryv, ilo+1, e)
// [ilo] is now to the left
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - XXX
if jhi-ilo == 1 {
x := M.entryv[ilo]
if x.Value != v {
vInsert__RangedMap_str(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_str("\tpresplit copy %s\t-> %s\n", x, M)
} else {
// XXX extend left/right if needed XXX here?
}
}
if xl.Value != v {
}
// entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values
if (jhi - ilo) > 1 {
......@@ -192,6 +261,7 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
}
// done
*/
}
// DelRange removes range r from the map.
......@@ -206,6 +276,12 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
M.verify()
defer M.verify()
M.delRange(r)
}
// delRange deletes range r from the map and returns .entryv index where r
// should be inserted/appended if needed.
func (M *_RangedMap_str) delRange(r KeyRange) (i int) {
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -215,7 +291,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
if ilo == l { // not found
debugf_RangedMap_str("\tnon-overlap right\n")
return
return l
}
// find last jhi: [jhi].Lo < r.hi
......@@ -233,9 +309,11 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
if jhi == 0 {
debugf_RangedMap_str("\tnon-overlap left\n")
return
return 0
}
// XXX if jhi - ilo == 0 { return "non-overlap" } ?
// [ilo+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked,
// or split+shrinked if ilo==jhi-1 and r is inside [ilo]
......@@ -262,6 +340,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
}
// done
return ilo
}
// HasRange returns whether all keys from range r belong to the map.
......@@ -288,7 +367,7 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false
}
// scan right and verify that whole r is covered
lo := r.Lo
for {
e := M.entryv[ilo]
......@@ -298,7 +377,7 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false // hole in coverage
}
if r.Hi_ <= e.Hi_ {
return true // full coverage
return true // reached full coverage
}
lo = e.Hi_
......@@ -311,10 +390,6 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false // r's right not fully covered
}
}
// // all keys from r are in M if r ∈ [ilo] XXX not in case of different values
// return (M.entryv[ilo].Lo <= r.Lo && r.Hi_ <= M.entryv[ilo].Hi_)
}
......
......@@ -117,6 +117,36 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
M.verify()
defer M.verify()
// clear range for r and insert new entry
// TODO optimize for set case (just merge all covered entries into one)
i := M.delRange(r)
vInsert__RangedMap_void(&M.entryv, i, e)
debugf_RangedMap_void("\tinsert %s\t-> %s\n", e, M)
// check if we should merge inserted entry with right/left neighbours
if i+1 < len(M.entryv) { // right
x := M.entryv[i]
right := M.entryv[i+1]
if (x.Hi_+1 == right.Lo) && (v == right.Value) {
vReplaceSlice__RangedMap_void(&M.entryv, i,i+2,
_RangedMap_voidEntry{v, KeyRange{x.Lo, right.Hi_}})
debugf_RangedMap_void("\tmerge right\t-> %s\n", M)
}
}
if i > 0 { // left
left := M.entryv[i-1]
x := M.entryv[i]
if (left.Hi_+1 == x.Lo) && (left.Value == v) {
vReplaceSlice__RangedMap_void(&M.entryv, i-1,i+1,
_RangedMap_voidEntry{v, KeyRange{left.Lo, x.Hi_}})
debugf_RangedMap_void("\tmerge left\t-> %s\n", M)
}
}
// done
/*
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -143,6 +173,45 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
}
debugf_RangedMap_void("\tjhi: %d\n", jhi)
// [ilo+1:jhi-1] should be deleted
if (jhi - ilo) > 2 {
vDeleteSlice__RangedMap_void(&M.entryv, ilo+1,jhi-1)
debugf_RangedMap_void("\tdelete M[%d:%d]\t-> %s\n", ilo+1, jhi-1, M)
}
// if r was overlapping with sole region -> presplit it TODO only if !vsame
x := M.entryv[ilo]
if jhi-ilo == 1 && x.Lo < r.Lo && r.Hi_ < x.Hi_ {
vInsert__RangedMap_void(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_void("\tpresplit copy %s\t-> %s\n", x, M)
}
jhi = -1 // no longer valid
// create new entry
// now it is
vInsert__RangedMap_void(&M.entryv, ilo+1, e)
// [ilo] is now to the left
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - XXX
if jhi-ilo == 1 {
x := M.entryv[ilo]
if x.Value != v {
vInsert__RangedMap_void(&M.entryv, ilo, x)
jhi++
debugf_RangedMap_void("\tpresplit copy %s\t-> %s\n", x, M)
} else {
// XXX extend left/right if needed XXX here?
}
}
if xl.Value != v {
}
// entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values
if (jhi - ilo) > 1 {
......@@ -192,6 +261,7 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
}
// done
*/
}
// DelRange removes range r from the map.
......@@ -206,6 +276,12 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
M.verify()
defer M.verify()
M.delRange(r)
}
// delRange deletes range r from the map and returns .entryv index where r
// should be inserted/appended if needed.
func (M *_RangedMap_void) delRange(r KeyRange) (i int) {
// find first ilo: r.Lo < [ilo].hi
l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool {
......@@ -215,7 +291,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
if ilo == l { // not found
debugf_RangedMap_void("\tnon-overlap right\n")
return
return l
}
// find last jhi: [jhi].Lo < r.hi
......@@ -233,9 +309,11 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
if jhi == 0 {
debugf_RangedMap_void("\tnon-overlap left\n")
return
return 0
}
// XXX if jhi - ilo == 0 { return "non-overlap" } ?
// [ilo+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked,
// or split+shrinked if ilo==jhi-1 and r is inside [ilo]
......@@ -262,6 +340,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
}
// done
return ilo
}
// HasRange returns whether all keys from range r belong to the map.
......@@ -288,7 +367,7 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false
}
// scan right and verify that whole r is covered
lo := r.Lo
for {
e := M.entryv[ilo]
......@@ -298,7 +377,7 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false // hole in coverage
}
if r.Hi_ <= e.Hi_ {
return true // full coverage
return true // reached full coverage
}
lo = e.Hi_
......@@ -311,10 +390,6 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false // r's right not fully covered
}
}
// // all keys from r are in M if r ∈ [ilo] XXX not in case of different values
// return (M.entryv[ilo].Lo <= r.Lo && r.Hi_ <= M.entryv[ilo].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