Commit 811610f0 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 67bc4254
...@@ -140,8 +140,14 @@ func (t *Tree) dump() string { ...@@ -140,8 +140,14 @@ func (t *Tree) dump() string {
return s return s
} }
type treeOp int
const (
opSet treeOp = iota
opDel
)
// rescan t from root and check that hit D, P, Kmin/Kmax and rest all match what they should // rescan t from root and check that hit D, P, Kmin/Kmax and rest all match what they should
func (t *Tree) checkHit(k interface{} /*K*/) { func (t *Tree) checkHit(k interface{} /*K*/, op treeOp) {
wrong := false wrong := false
bad := func(s string, va ...interface{}) { bad := func(s string, va ...interface{}) {
dbg(s, va...) dbg(s, va...)
...@@ -149,10 +155,9 @@ func (t *Tree) checkHit(k interface{} /*K*/) { ...@@ -149,10 +155,9 @@ func (t *Tree) checkHit(k interface{} /*K*/) {
} }
q := t.r q := t.r
var p *x
pi := -1
var dd *d var dd *d
var i int var p *x
i, pi := -1, -1
var ok bool var ok bool
var hitKmin, hitKmax xkey var hitKmin, hitKmax xkey
...@@ -163,6 +168,11 @@ loop: ...@@ -163,6 +168,11 @@ loop:
// the logic to get hitKmin/hitKmax & friends is simpler compared to // the logic to get hitKmin/hitKmax & friends is simpler compared to
// that in Set when splitX may occurr. // that in Set when splitX may occurr.
for { for {
// empty tree
if q == nil {
break
}
i, ok = t.find(q, k) i, ok = t.find(q, k)
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
...@@ -194,8 +204,14 @@ loop: ...@@ -194,8 +204,14 @@ loop:
case *d: case *d:
if !ok { switch {
case op == opSet && !ok:
bad("key %v not found after set", k) bad("key %v not found after set", k)
case op == opDel && ok:
bad("key %v found after delete", k)
// XXX adjust i to be in range for opDel
} }
dd = x dd = x
......
...@@ -308,22 +308,80 @@ func (t *Tree) catX(p, q, r *x, pi int) { ...@@ -308,22 +308,80 @@ func (t *Tree) catX(p, q, r *x, pi int) {
// true. // true.
func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
//dbg("--- PRE Delete(%v)\n%s", k, t.dump()) //dbg("--- PRE Delete(%v)\n%s", k, t.dump())
defer t.checkHit(k) //defer t.checkHit(k, opDel)
//defer func() { //defer func() {
// dbg("--- POST\n%s\n====\n", t.dump()) // dbg("--- POST\n%s\n====\n", t.dump())
//}() //}()
// TODO audit for hit update // check if we can do the delete nearby previous change
/*
i, ok := t.hitFind(k)
if i >= 0 {
//dbg("hit found\t-> %d, %v", i, ok)
//dd := t.hitD
switch {
case !ok:
t.hitDi = i // XXX ok ? (i > h)
return false
// here: need to extract / underflow but check to not underflow too much XXX
default:
// TODO
}
}
*/
// data page not quickly found - search and descent from root
pi := -1 pi := -1
var p *x var p *x
q := t.r q := t.r
if q == nil { if q == nil {
// XXX update hit ?
return false return false
} }
//var hitKmin, hitKmax xkey // initially [-∞, +∞)
//var hitPKmax xkey // Kmax for whole hitP
for { for {
var i int i, ok := t.find(q, k)
i, ok = t.find(q, k) switch x := q.(type) {
case *x:
if x.c < kx && q != t.r {
x, i = t.underflowX(p, x, pi, i)
}
p = x
pi = i
if ok {
pi++
}
q = x.x[pi].ch
case *d:
if !ok {
return false
}
t.extract(x, i)
if x.c >= kd {
return true
}
if q != t.r {
t.underflow(p, x, pi) // hit
} else if t.c == 0 {
t.Clear() // hit
}
return true
}
}
/*
if ok { if ok {
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
...@@ -336,7 +394,7 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { ...@@ -336,7 +394,7 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
ok = false ok = false
continue continue
case *d: case *d:
t.extract(x, i) // hit t.extract(x, i)
if x.c >= kd { if x.c >= kd {
return true return true
} }
...@@ -359,13 +417,14 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { ...@@ -359,13 +417,14 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
p = x p = x
q = x.x[i].ch q = x.x[i].ch
case *d: case *d:
return false // hit return false
} }
} }
*/
} }
func (t *Tree) extract(q *d, i int) { // (r interface{} /*V*/) { func (t *Tree) extract(q *d, i int) { // (r interface{} /*V*/) {
// XXX update hit ? // XXX update hit
t.ver++ t.ver++
//r = q.d[i].v // prepared for Extract //r = q.d[i].v // prepared for Extract
q.c-- q.c--
...@@ -629,13 +688,14 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) { ...@@ -629,13 +688,14 @@ 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) PKmax: %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmax, t.dump()) //dbg("--- PRE Set(%v, %v)\t(%v @%d, [%v, %v) PKmax: %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmax, t.dump())
defer t.checkHit(k) //defer t.checkHit(k, opSet)
//defer func() { //defer func() {
// 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)
...@@ -665,6 +725,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -665,6 +725,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
} }
} }
} }
*/
// data page not quickly found - search and descent from root // data page not quickly found - search and descent from root
pi := -1 pi := -1
...@@ -681,7 +742,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -681,7 +742,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
var hitPKmax xkey // Kmax for whole hitP var hitPKmax xkey // Kmax for whole hitP
for { for {
i, ok = t.find(q, k) i, ok := t.find(q, k)
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
//hitPKmax = hitKmax //hitPKmax = hitKmax
...@@ -714,7 +775,6 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -714,7 +775,6 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if ok { if ok {
pi++ pi++
} }
q = p.x[pi].ch q = p.x[pi].ch
if pi > 0 { if pi > 0 {
......
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