Commit aa8accd7 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6397d666
...@@ -27,6 +27,7 @@ var caller = func(s string, va ...interface{}) { ...@@ -27,6 +27,7 @@ var caller = func(s string, va ...interface{}) {
} }
func dbg(s string, va ...interface{}) { func dbg(s string, va ...interface{}) {
return
if s == "" { if s == "" {
s = strings.Repeat("%v ", len(va)) s = strings.Repeat("%v ", len(va))
} }
...@@ -234,7 +235,7 @@ func TestSetGet1(t *testing.T) { ...@@ -234,7 +235,7 @@ func TestSetGet1(t *testing.T) {
for i := range a { for i := range a {
a[i] = (i ^ x) << 1 a[i] = (i ^ x) << 1
} }
//dbg("", a) dbg("", a)
for i, k := range a { for i, k := range a {
set(k, k^x) set(k, k^x)
if g, e := r.Len(), i+1; g != e { if g, e := r.Len(), i+1; g != e {
......
...@@ -41,6 +41,7 @@ func (p *btTpool) get(cmp Cmp) *Tree { ...@@ -41,6 +41,7 @@ func (p *btTpool) get(cmp Cmp) *Tree {
x.cmp = cmp x.cmp = cmp
x.hitIdx = -1 x.hitIdx = -1
x.hitPi = -1 x.hitPi = -1
x.hitMinKMInf = true
x.hitMaxKInf = true x.hitMaxKInf = true
return x return x
} }
...@@ -108,8 +109,10 @@ type ( ...@@ -108,8 +109,10 @@ type (
hitP *x hitP *x
hitPi int hitPi int
hitMaxK interface{} /*K*/ hitMinK interface{} /*K*/
hitMaxKInf bool // whether hitMaxK = ∞ hitMinKMInf bool // whether hitMinK = -∞
hitMaxK interface{} /*K*/
hitMaxKInf bool // whether hitMaxK = +∞
} }
xe struct { // x element xe struct { // x element
...@@ -434,8 +437,8 @@ func (t *Tree) hitFind(k interface{} /*K*/) (i int, ok bool) { ...@@ -434,8 +437,8 @@ func (t *Tree) hitFind(k interface{} /*K*/) (i int, ok bool) {
} }
i = t.hitIdx i = t.hitIdx
p := t.hitP //p := t.hitP
pi := t.hitPi //pi := t.hitPi
switch cmp := t.cmp(k, hit.d[i].k); { switch cmp := t.cmp(k, hit.d[i].k); {
case cmp > 0: case cmp > 0:
...@@ -461,8 +464,12 @@ func (t *Tree) hitFind(k interface{} /*K*/) (i int, ok bool) { ...@@ -461,8 +464,12 @@ func (t *Tree) hitFind(k interface{} /*K*/) (i int, ok bool) {
*/ */
case cmp < 0: case cmp < 0:
// in hit range: >= pprev.k // // in hit range: >= pprev.k
if p != nil && pi > 0 && t.cmp(k, p.x[pi-1].k) < 0 { // if p != nil && pi > 0 && t.cmp(k, p.x[pi-1].k) < 0 {
// return -1, false
// }
if !(t.hitMinKMInf || t.cmp(k, t.hitMinK) >= 0) {
return -1, false return -1, false
} }
...@@ -634,30 +641,30 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) { ...@@ -634,30 +641,30 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) {
// Set sets the value associated with k. // Set sets the value associated with k.
func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
//dbg("--- PRE Set(%v, %v)\t(%v @%d, %v/%v, %v @%d)\n%s", k, v, t.hit, t.hitIdx, t.hitMaxKInf, t.hitMaxK, t.hitP, t.hitPi, t.dump()) dbg("--- PRE Set(%v, %v)\t(%v @%d, [%v/%v, %v/%v), %v @%d)\n%s", k, v, t.hit, t.hitIdx, t.hitMinKMInf, t.hitMinK, t.hitMaxKInf, t.hitMaxK, t.hitP, t.hitPi, t.dump())
//defer func() { defer func() {
// //if r := recover(); r != nil { //if r := recover(); r != nil {
// // panic(r) // panic(r)
// //} //}
// dbg("--- POST\n%s\n====\n", t.dump()) dbg("--- POST\n%s\n====\n", t.dump())
//}() }()
// check if we can do the update nearby previous change // check if we can do the update nearby previous change
i, ok := t.hitFind(k) i, ok := t.hitFind(k)
if i >= 0 { if i >= 0 {
//dbg("hit found\t-> %d, %v", i, ok) dbg("hit found\t-> %d, %v", i, ok)
//dd, p, pi := t.hit, t.hitP, t.hitPi //dd, p, pi := t.hit, t.hitP, t.hitPi
dd := t.hit dd := t.hit
switch { switch {
case ok: case ok:
//dbg("ok'") dbg("ok'")
dd.d[i].v = v dd.d[i].v = v
t.hitIdx = i t.hitIdx = i
return return
case dd.c < 2*kd: case dd.c < 2*kd:
//dbg("insert'") dbg("insert'")
t.insert(dd, i, k, v) t.insert(dd, i, k, v)
return return
...@@ -684,8 +691,8 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -684,8 +691,8 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
return return
} }
var maxK interface{} /*K*/ // XXX max key limiting found hit range var minK, maxK interface{} /*K*/ // XXX max key limiting found hit range
maxKInf := true // if there will be no limiting factors ... XXX minKMInf, maxKInf := true, true // if there will be no limiting factors ... XXX
for { for {
i, ok = t.find(q, k) i, ok = t.find(q, k)
...@@ -703,12 +710,22 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -703,12 +710,22 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
p = x p = x
q = p.x[pi].ch q = p.x[pi].ch
if pi > 0 {
minK = p.x[pi-1].k
minKMInf = false
}
if pi < p.c { if pi < p.c {
maxK = p.x[pi].k maxK = p.x[pi].k
maxKInf = false maxKInf = false
} }
if minK != nil && minKMInf {
dbg("MINK WRONG", pi, minK)
panic(minK)
}
if maxK != nil && maxKInf { if maxK != nil && maxKInf {
dbg("", pi, maxK) dbg("MAXK WRONG", pi, maxK)
panic(maxK) panic(maxK)
} }
...@@ -716,23 +733,29 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -716,23 +733,29 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
// data page found - perform the update // data page found - perform the update
switch { switch {
case ok: case ok:
//dbg("ok") dbg("ok")
x.d[i].v = v x.d[i].v = v
t.hit, t.hitIdx = x, i t.hit, t.hitIdx = x, i
t.hitP, t.hitPi = p, pi t.hitP, t.hitPi = p, pi
t.hitMinK = minK
t.hitMinKMInf = minKMInf
t.hitMaxK = maxK t.hitMaxK = maxK
t.hitMaxKInf = maxKInf t.hitMaxKInf = maxKInf
case x.c < 2*kd: case x.c < 2*kd:
//dbg("insert") dbg("insert")
t.insert(x, i, k, v) t.insert(x, i, k, v)
t.hitP, t.hitPi = p, pi t.hitP, t.hitPi = p, pi
t.hitMinK = minK
t.hitMinKMInf = minKMInf
t.hitMaxK = maxK t.hitMaxK = maxK
t.hitMaxKInf = maxKInf t.hitMaxKInf = maxKInf
default: default:
//dbg("overflow") dbg("overflow")
t.overflow(p, x, pi, i, k, v) t.overflow(p, x, pi, i, k, v)
t.hitMinK = minK
t.hitMinKMInf = minKMInf
t.hitMaxK = maxK t.hitMaxK = maxK
t.hitMaxKInf = maxKInf t.hitMaxKInf = maxKInf
} }
......
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