Commit e81232be authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 99393706
...@@ -162,7 +162,7 @@ func (q *x) extract(i int) { ...@@ -162,7 +162,7 @@ func (q *x) extract(i int) {
} }
func (q *x) insert(i int, k interface{} /*K*/, ch interface{}) *x { func (q *x) insert(i int, k interface{} /*K*/, ch interface{}) *x {
dbg("X.insert %v @%d", q, i) //dbg("X.insert %v @%d", q, i)
c := q.c c := q.c
if i < c { if i < c {
q.x[c+1].ch = q.x[c].ch q.x[c+1].ch = q.x[c].ch
...@@ -626,75 +626,94 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) { ...@@ -626,75 +626,94 @@ 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 @%d)\n%s", k, v, t.hit, t.hitIdx, t.hitP, t.hitPi, t.dump()) //dbg("--- PRE Set(%v, %v)\t(%v @%d, %v @%d)\n%s", k, v, t.hit, t.hitIdx, 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())
}() //}()
pi := -1
var p *x
var dd *d
// 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
// data page not quickly found - search and descent from root switch {
} else { case ok:
q := t.r //dbg("ok'")
if q == nil { dd.d[i].v = v
dbg("empty") t.hitIdx = i
z := t.insert(btDPool.Get().(*d), 0, k, v) // XXX update hit
t.r, t.first, t.last = z, z, z
return return
}
loop: case dd.c < 2*kd:
for { //dbg("insert'")
i, ok = t.find(q, k) t.insert(dd, i, k, v)
switch x := q.(type) { return
case *x:
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
p = x
if ok {
pi = i + 1
q = x.x[i+1].ch
} else {
pi = i
q = x.x[i].ch
}
case *d: case p == nil || p.c <= 2*kx:
dd = x //dbg("overflow'")
break loop t.overflow(p, dd, pi, i, k, v)
} return
default:
// here: need to overflow but p.c > 2*kx -> need to do
// the usual scan to split index pages
} }
} }
// data page found - perform the update // data page not quickly found - search and descent from root
switch { pi := -1
case ok: var p *x
dbg("ok") q := t.r
dd.d[i].v = v
t.hit, t.hitIdx = dd, i
t.hitP, t.hitPi = p, pi
case dd.c < 2*kd: if q == nil {
dbg("insert") //dbg("empty")
t.insert(dd, i, k, v) z := t.insert(btDPool.Get().(*d), 0, k, v) // XXX update hit
t.hitP, t.hitPi = p, pi t.r, t.first, t.last = z, z, z
return
}
default: for {
dbg("overflow") i, ok = t.find(q, k)
t.overflow(p, dd, pi, i, k, v) switch x := q.(type) {
case *x:
if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i)
}
p = x
if ok {
pi = i + 1
q = x.x[i+1].ch
} else {
pi = i
q = x.x[i].ch
}
case *d:
// data page found - perform the update
switch {
case ok:
//dbg("ok")
x.d[i].v = v
t.hit, t.hitIdx = x, i
t.hitP, t.hitPi = p, pi
case x.c < 2*kd:
//dbg("insert")
t.insert(x, i, k, v)
t.hitP, t.hitPi = p, pi
default:
//dbg("overflow")
t.overflow(p, x, pi, i, k, v)
}
return
}
} }
} }
// Put combines Get and Set in a more efficient way where the tree is walked // Put combines Get and Set in a more efficient way where the tree is walked
......
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