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) { ...@@ -115,6 +115,36 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -141,6 +171,45 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) { ...@@ -141,6 +171,45 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
} }
debugfRMap("\tjhi: %d\n", jhi) 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 // entries in [ilo:jhi) [r.Lo,r.hi) and should be merged into one
// FIXME check different values // FIXME check different values
if (jhi - ilo) > 1 { if (jhi - ilo) > 1 {
...@@ -190,6 +259,7 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) { ...@@ -190,6 +259,7 @@ func (M *RangedMap) SetRange(r KeyRange, v VALUE) {
} }
// done // done
*/
} }
// DelRange removes range r from the map. // DelRange removes range r from the map.
...@@ -204,6 +274,12 @@ func (M *RangedMap) DelRange(r KeyRange) { ...@@ -204,6 +274,12 @@ func (M *RangedMap) DelRange(r KeyRange) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -213,7 +289,7 @@ func (M *RangedMap) DelRange(r KeyRange) { ...@@ -213,7 +289,7 @@ func (M *RangedMap) DelRange(r KeyRange) {
if ilo == l { // not found if ilo == l { // not found
debugfRMap("\tnon-overlap right\n") debugfRMap("\tnon-overlap right\n")
return return l
} }
// find last jhi: [jhi].Lo < r.hi // find last jhi: [jhi].Lo < r.hi
...@@ -231,9 +307,11 @@ func (M *RangedMap) DelRange(r KeyRange) { ...@@ -231,9 +307,11 @@ func (M *RangedMap) DelRange(r KeyRange) {
if jhi == 0 { if jhi == 0 {
debugfRMap("\tnon-overlap left\n") debugfRMap("\tnon-overlap left\n")
return return 0
} }
// XXX if jhi - ilo == 0 { return "non-overlap" } ?
// [ilo+1:jhi-1] should be deleted // [ilo+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked, // [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] // or split+shrinked if ilo==jhi-1 and r is inside [ilo]
...@@ -260,6 +338,7 @@ func (M *RangedMap) DelRange(r KeyRange) { ...@@ -260,6 +338,7 @@ func (M *RangedMap) DelRange(r KeyRange) {
} }
// done // done
return ilo
} }
// HasRange returns whether all keys from range r belong to the map. // HasRange returns whether all keys from range r belong to the map.
...@@ -286,7 +365,6 @@ func (M *RangedMap) HasRange(r KeyRange) (yes bool) { ...@@ -286,7 +365,6 @@ func (M *RangedMap) HasRange(r KeyRange) (yes bool) {
return false return false
} }
// scan right and verify that whole r is covered // scan right and verify that whole r is covered
lo := r.Lo lo := r.Lo
for { for {
......
...@@ -34,15 +34,15 @@ func TestRangedMap(t *testing.T) { ...@@ -34,15 +34,15 @@ func TestRangedMap(t *testing.T) {
A *RangedMap A *RangedMap
B RangedMapEntry B RangedMapEntry
Set *RangedMap // A.SetRange(B.keycov, B.value) Set *RangedMap // A.SetRange(B.keycov, B.value)
Del *RangedMap // A.DelRange(B) Del *RangedMap // A.DelRange(B.keycov)
Has bool // A.HasRange(B) Has bool // A.HasRange(B.keycov)
// XXX Get? // XXX Get?
} }
E := func(A *RangedMap, B RangedMapEntry, S, D *RangedMap, H bool) testEntry { E := func(A *RangedMap, B RangedMapEntry, S, D *RangedMap, H bool) testEntry {
return testEntry{A, B, S, D, H} 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 { M := func(argv ...interface{}) *RangedMap {
l := len(argv) l := len(argv)
if l % 3 != 0 { if l % 3 != 0 {
......
...@@ -122,6 +122,12 @@ func TestRangedKeySet(t *testing.T) { ...@@ -122,6 +122,12 @@ func TestRangedKeySet(t *testing.T) {
S(noo, oo), // U S(noo, oo), // U
S()), // D 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) // [1,3) [5,7) + insert [3,5) -> [1,7)
E( E(
S(1,3, 5,7), // A S(1,3, 5,7), // A
......
...@@ -117,6 +117,36 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) { ...@@ -117,6 +117,36 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -143,6 +173,45 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) { ...@@ -143,6 +173,45 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
} }
debugf_RangedMap_str("\tjhi: %d\n", jhi) 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 // entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values // FIXME check different values
if (jhi - ilo) > 1 { if (jhi - ilo) > 1 {
...@@ -192,6 +261,7 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) { ...@@ -192,6 +261,7 @@ func (M *_RangedMap_str) SetRange(r KeyRange, v string) {
} }
// done // done
*/
} }
// DelRange removes range r from the map. // DelRange removes range r from the map.
...@@ -206,6 +276,12 @@ func (M *_RangedMap_str) DelRange(r KeyRange) { ...@@ -206,6 +276,12 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -215,7 +291,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) { ...@@ -215,7 +291,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
if ilo == l { // not found if ilo == l { // not found
debugf_RangedMap_str("\tnon-overlap right\n") debugf_RangedMap_str("\tnon-overlap right\n")
return return l
} }
// find last jhi: [jhi].Lo < r.hi // find last jhi: [jhi].Lo < r.hi
...@@ -233,9 +309,11 @@ func (M *_RangedMap_str) DelRange(r KeyRange) { ...@@ -233,9 +309,11 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
if jhi == 0 { if jhi == 0 {
debugf_RangedMap_str("\tnon-overlap left\n") 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+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked, // [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] // or split+shrinked if ilo==jhi-1 and r is inside [ilo]
...@@ -262,6 +340,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) { ...@@ -262,6 +340,7 @@ func (M *_RangedMap_str) DelRange(r KeyRange) {
} }
// done // done
return ilo
} }
// HasRange returns whether all keys from range r belong to the map. // 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) { ...@@ -288,7 +367,7 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false return false
} }
// scan right and verify that whole r is covered
lo := r.Lo lo := r.Lo
for { for {
e := M.entryv[ilo] e := M.entryv[ilo]
...@@ -298,7 +377,7 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) { ...@@ -298,7 +377,7 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false // hole in coverage return false // hole in coverage
} }
if r.Hi_ <= e.Hi_ { if r.Hi_ <= e.Hi_ {
return true // full coverage return true // reached full coverage
} }
lo = e.Hi_ lo = e.Hi_
...@@ -311,10 +390,6 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) { ...@@ -311,10 +390,6 @@ func (M *_RangedMap_str) HasRange(r KeyRange) (yes bool) {
return false // r's right not fully covered 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) { ...@@ -117,6 +117,36 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -143,6 +173,45 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) { ...@@ -143,6 +173,45 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
} }
debugf_RangedMap_void("\tjhi: %d\n", jhi) 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 // entries in [ilo:jhi) ∈ [r.Lo,r.hi) and should be merged into one
// FIXME check different values // FIXME check different values
if (jhi - ilo) > 1 { if (jhi - ilo) > 1 {
...@@ -192,6 +261,7 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) { ...@@ -192,6 +261,7 @@ func (M *_RangedMap_void) SetRange(r KeyRange, v void) {
} }
// done // done
*/
} }
// DelRange removes range r from the map. // DelRange removes range r from the map.
...@@ -206,6 +276,12 @@ func (M *_RangedMap_void) DelRange(r KeyRange) { ...@@ -206,6 +276,12 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
M.verify() M.verify()
defer 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 // find first ilo: r.Lo < [ilo].hi
l := len(M.entryv) l := len(M.entryv)
ilo := sort.Search(l, func(i int) bool { ilo := sort.Search(l, func(i int) bool {
...@@ -215,7 +291,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) { ...@@ -215,7 +291,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
if ilo == l { // not found if ilo == l { // not found
debugf_RangedMap_void("\tnon-overlap right\n") debugf_RangedMap_void("\tnon-overlap right\n")
return return l
} }
// find last jhi: [jhi].Lo < r.hi // find last jhi: [jhi].Lo < r.hi
...@@ -233,9 +309,11 @@ func (M *_RangedMap_void) DelRange(r KeyRange) { ...@@ -233,9 +309,11 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
if jhi == 0 { if jhi == 0 {
debugf_RangedMap_void("\tnon-overlap left\n") 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+1:jhi-1] should be deleted
// [ilo] and [jhi-1] overlap with [r.lo,r.hi) - they should be deleted, or shrinked, // [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] // or split+shrinked if ilo==jhi-1 and r is inside [ilo]
...@@ -262,6 +340,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) { ...@@ -262,6 +340,7 @@ func (M *_RangedMap_void) DelRange(r KeyRange) {
} }
// done // done
return ilo
} }
// HasRange returns whether all keys from range r belong to the map. // 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) { ...@@ -288,7 +367,7 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false return false
} }
// scan right and verify that whole r is covered
lo := r.Lo lo := r.Lo
for { for {
e := M.entryv[ilo] e := M.entryv[ilo]
...@@ -298,7 +377,7 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) { ...@@ -298,7 +377,7 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false // hole in coverage return false // hole in coverage
} }
if r.Hi_ <= e.Hi_ { if r.Hi_ <= e.Hi_ {
return true // full coverage return true // reached full coverage
} }
lo = e.Hi_ lo = e.Hi_
...@@ -311,10 +390,6 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) { ...@@ -311,10 +390,6 @@ func (M *_RangedMap_void) HasRange(r KeyRange) (yes bool) {
return false // r's right not fully covered 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