Commit bd3f6889 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent d98ed0e1
...@@ -11,10 +11,10 @@ import ( ...@@ -11,10 +11,10 @@ import (
) )
const ( const (
//kx = 32 //TODO benchmark tune this number if using custom key/value type(s). kx = 32 //TODO benchmark tune this number if using custom key/value type(s).
//kd = 32 //TODO benchmark tune this number if using custom key/value type(s). kd = 32 //TODO benchmark tune this number if using custom key/value type(s).
kx = 2 //kx = 2
kd = 2 //kd = 2
) )
func init() { func init() {
...@@ -311,7 +311,7 @@ func (t *Tree) catX(p, q, r *x, pi int) { ...@@ -311,7 +311,7 @@ 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)\t; %v @%d, [%v, %v) pk: [%v, %v)\n%s", k, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax, t.dump()) //dbg("--- PRE Delete(%v)\t; %v @%d, [%v, %v) pk: [%v, %v)\n%s", k, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax, t.dump())
defer t.checkHit(k, opDel) //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())
//}() //}()
...@@ -718,7 +718,7 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) { ...@@ -718,7 +718,7 @@ 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) pk: [%v, %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax, t.dump()) //dbg("--- PRE Set(%v, %v)\t; %v @%d, [%v, %v) pk: [%v, %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax, t.dump())
defer t.checkHit(k, opSet) //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())
//}() //}()
...@@ -832,7 +832,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -832,7 +832,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
// //
// modulo the differing return values. // modulo the differing return values.
func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists bool) (newV interface{} /*V*/, write bool)) (oldV interface{} /*V*/, written bool) { func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists bool) (newV interface{} /*V*/, write bool)) (oldV interface{} /*V*/, written bool) {
defer func () { t.checkHit(k, opPut(written)) }() //defer func () { t.checkHit(k, opPut(written)) }()
pi := -1 pi := -1
var p *x var p *x
q := t.r q := t.r
......
...@@ -105,10 +105,16 @@ type ( ...@@ -105,10 +105,16 @@ type (
hitDi int hitDi int
hitP *x // parent & pos for data page (= nil/-1 if no parent) hitP *x // parent & pos for data page (= nil/-1 if no parent)
hitPi int hitPi int
hitKmin xkey // hitD allowed key range is [hitKmin, hitKmax)
hitKmax xkey hitKmin int // hitD allowed key range is [hitKmin, hitKmax)
hitPKmin xkey // ----//--- for hitP hitKmax int
hitPKmax xkey hitPKmin int // ----//--- for hitP
hitPKmax int
hitKminSet bool // whether corresponding hitK* value is set
hitKmaxSet bool // if value is not set it is treated as ±∞ depending on context
hitPKminSet bool
hitPKmaxSet bool
} }
xe struct { // x element xe struct { // x element
...@@ -120,11 +126,6 @@ type ( ...@@ -120,11 +126,6 @@ type (
c int c int
x [2*kx + 2]xe x [2*kx + 2]xe
} }
xkey struct { // key + whether value is present at all
k int
kset bool // if not set - k not present
}
) )
var ( // R/O zero values var ( // R/O zero values
...@@ -151,10 +152,10 @@ func clr(q interface{}) { ...@@ -151,10 +152,10 @@ func clr(q interface{}) {
} }
} }
func (xk *xkey) set(k int) { func (t *Tree) setHitKmin(k int) { t.hitKmin = k; t.hitKminSet = true }
xk.k = k func (t *Tree) setHitKmax(k int) { t.hitKmax = k; t.hitKmaxSet = true }
xk.kset = true func (t *Tree) setHitPKmin(k int) { t.hitPKmin = k; t.hitPKminSet = true }
} func (t *Tree) setHitPKmax(k int) { t.hitPKmax = k; t.hitPKmaxSet = true }
// -------------------------------------------------------------------------- x // -------------------------------------------------------------------------- x
...@@ -233,7 +234,8 @@ func (t *Tree) Clear() { ...@@ -233,7 +234,8 @@ func (t *Tree) Clear() {
clr(t.r) clr(t.r)
t.c, t.first, t.last, t.r = 0, nil, nil, nil t.c, t.first, t.last, t.r = 0, nil, nil, nil
t.hitD, t.hitDi, t.hitP, t.hitPi = nil, -1, nil, -1 t.hitD, t.hitDi, t.hitP, t.hitPi = nil, -1, nil, -1
t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax = xkey{}, xkey{}, xkey{}, xkey{} t.hitKmin, t.hitKmax, t.hitPKmin, t.hitPKmax = zk, zk, zk, zk
t.hitKminSet, t.hitKmaxSet, t.hitPKminSet, t.hitPKmaxSet = false, false, false, false
t.ver++ t.ver++
} }
...@@ -372,8 +374,8 @@ func (t *Tree) Delete(k int) (ok bool) { ...@@ -372,8 +374,8 @@ func (t *Tree) Delete(k int) (ok bool) {
return false return false
} }
t.hitKmin, t.hitKmax = xkey{}, xkey{} // initially [-∞, +∞) t.hitKminSet, t.hitKmaxSet = false, false // initially [-∞, +∞)
t.hitPKmin, t.hitPKmax = xkey{}, xkey{} t.hitPKminSet, t.hitPKmaxSet = false, false
for { for {
i, ok := t.find(q, k) i, ok := t.find(q, k)
...@@ -390,17 +392,19 @@ func (t *Tree) Delete(k int) (ok bool) { ...@@ -390,17 +392,19 @@ func (t *Tree) Delete(k int) (ok bool) {
t.hitPKmin = t.hitKmin t.hitPKmin = t.hitKmin
t.hitPKmax = t.hitKmax t.hitPKmax = t.hitKmax
t.hitPKminSet = t.hitKminSet
t.hitPKmaxSet = t.hitKmaxSet
p = x p = x
pi = i pi = i
q = x.x[pi].ch q = x.x[pi].ch
if pi > 0 { // k=-∞ @-1 if pi > 0 { // k=-∞ @-1
t.hitKmin.set(p.x[pi-1].k) t.setHitKmin(p.x[pi-1].k)
} }
if pi < p.c { // k=+∞ @p.c if pi < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} }
case *d: case *d:
...@@ -528,7 +532,7 @@ func (t *Tree) hitFind(k int) (i int, ok bool) { ...@@ -528,7 +532,7 @@ func (t *Tree) hitFind(k int) (i int, ok bool) {
switch cmp := t.cmp(k, hit.d[i].k); { switch cmp := t.cmp(k, hit.d[i].k); {
case cmp > 0: case cmp > 0:
if t.hitKmax.kset && t.cmp(k, t.hitKmax.k) >= 0 { if t.hitKmaxSet && t.cmp(k, t.hitKmax) >= 0 {
// >= hitKmax // >= hitKmax
return -1, false return -1, false
} }
...@@ -537,7 +541,7 @@ func (t *Tree) hitFind(k int) (i int, ok bool) { ...@@ -537,7 +541,7 @@ func (t *Tree) hitFind(k int) (i int, ok bool) {
return t.find2(hit, k, i+1, hit.c-1) return t.find2(hit, k, i+1, hit.c-1)
case cmp < 0: case cmp < 0:
if t.hitKmin.kset && t.cmp(k, t.hitKmin.k) < 0 { if t.hitKminSet && t.cmp(k, t.hitKmin) < 0 {
// < hitKmin // < hitKmin
return -1, false return -1, false
} }
...@@ -626,7 +630,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { ...@@ -626,7 +630,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
l.mvL(q, 1) l.mvL(q, 1)
t.insert(q, i-1, k, v) t.insert(q, i-1, k, v)
p.x[pi-1].k = q.d[0].k p.x[pi-1].k = q.d[0].k
t.hitKmin.set(q.d[0].k) t.setHitKmin(q.d[0].k)
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
return return
} }
...@@ -636,7 +640,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { ...@@ -636,7 +640,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
q.mvR(r, 1) q.mvR(r, 1)
t.insert(q, i, k, v) t.insert(q, i, k, v)
p.x[pi].k = r.d[0].k p.x[pi].k = r.d[0].k
t.hitKmax.set(r.d[0].k) t.setHitKmax(r.d[0].k)
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
return return
} }
...@@ -644,10 +648,12 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { ...@@ -644,10 +648,12 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.insert(r, 0, k, v) t.insert(r, 0, k, v)
p.x[pi].k = k p.x[pi].k = k
t.hitKmin.set(k) t.setHitKmin(k)
t.hitKmax = t.hitPKmax
if pi+1 < p.c { // k=+∞ @p.c if pi+1 < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi+1].k) t.setHitKmax(p.x[pi+1].k)
} else {
t.hitKmax = t.hitPKmax
t.hitKmaxSet = t.hitPKmaxSet
} }
t.hitPi = pi + 1 t.hitPi = pi + 1
return return
...@@ -757,8 +763,8 @@ func (t *Tree) Set(k int, v int) { ...@@ -757,8 +763,8 @@ func (t *Tree) Set(k int, v int) {
return return
} }
t.hitKmin, t.hitKmax = xkey{}, xkey{} // initially [-∞, +∞) t.hitKminSet, t.hitKmaxSet = false, false // initially [-∞, +∞)
t.hitPKmin, t.hitPKmax = xkey{}, xkey{} t.hitPKminSet, t.hitPKmaxSet = false, false
for { for {
i, ok := t.find(q, k) i, ok := t.find(q, k)
...@@ -775,17 +781,19 @@ func (t *Tree) Set(k int, v int) { ...@@ -775,17 +781,19 @@ func (t *Tree) Set(k int, v int) {
t.hitPKmin = t.hitKmin t.hitPKmin = t.hitKmin
t.hitPKmax = t.hitKmax t.hitPKmax = t.hitKmax
t.hitPKminSet = t.hitKminSet
t.hitPKmaxSet = t.hitKmaxSet
p = x p = x
pi = i pi = i
q = p.x[pi].ch q = p.x[pi].ch
if pi > 0 { // k=-∞ @-1 if pi > 0 { // k=-∞ @-1
t.hitKmin.set(p.x[pi-1].k) t.setHitKmin(p.x[pi-1].k)
} }
if pi < p.c { // k=+∞ @p.c if pi < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} }
case *d: case *d:
...@@ -895,8 +903,8 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool) ...@@ -895,8 +903,8 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool)
} }
// data page not quickly found - search and descent from root // data page not quickly found - search and descent from root
t.hitKmin, t.hitKmax = xkey{}, xkey{} // initially [-∞, +∞) t.hitKminSet, t.hitKmaxSet = false, false // initially [-∞, +∞)
t.hitPKmin, t.hitPKmax = xkey{}, xkey{} t.hitPKminSet, t.hitPKmaxSet = false, false
for { for {
i, ok := t.find(q, k) i, ok := t.find(q, k)
...@@ -913,17 +921,19 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool) ...@@ -913,17 +921,19 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool)
t.hitPKmin = t.hitKmin t.hitPKmin = t.hitKmin
t.hitPKmax = t.hitKmax t.hitPKmax = t.hitKmax
t.hitPKminSet = t.hitKminSet
t.hitPKmaxSet = t.hitKmaxSet
p = x p = x
pi = i pi = i
q = p.x[pi].ch q = p.x[pi].ch
if pi > 0 { // k=-∞ @-1 if pi > 0 { // k=-∞ @-1
t.hitKmin.set(p.x[pi-1].k) t.setHitKmin(p.x[pi-1].k)
} }
if pi < p.c { // k=+∞ @p.c if pi < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} }
case *d: case *d:
...@@ -998,15 +1008,17 @@ func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) { ...@@ -998,15 +1008,17 @@ func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) {
if i > kd { if i > kd {
t.insert(r, i-kd, k, v) t.insert(r, i-kd, k, v)
t.hitKmin.set(p.x[pi].k) t.setHitKmin(p.x[pi].k)
t.hitKmax = t.hitPKmax
if pi+1 < p.c { // k=+∞ @p.c if pi+1 < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi+1].k) t.setHitKmax(p.x[pi+1].k)
} else {
t.hitKmax = t.hitPKmax
t.hitKmaxSet = t.hitPKmaxSet
} }
t.hitPi = pi + 1 t.hitPi = pi + 1
} else { } else {
t.insert(q, i, k, v) t.insert(q, i, k, v)
t.hitKmax.set(r.d[0].k) t.setHitKmax(r.d[0].k)
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
} }
} }
...@@ -1032,13 +1044,15 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -1032,13 +1044,15 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) {
if i > kx { if i > kx {
q = r q = r
i -= kx + 1 i -= kx + 1
t.hitKmin.set(p.x[pi].k) t.setHitKmin(p.x[pi].k)
t.hitKmax = t.hitPKmax
if pi+1 < p.c { // k=+∞ @p.c if pi+1 < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi+1].k) t.setHitKmax(p.x[pi+1].k)
} else {
t.hitKmax = t.hitPKmax
t.hitKmaxSet = t.hitPKmaxSet
} }
} else { } else {
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} }
return q, i return q, i
...@@ -1051,7 +1065,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -1051,7 +1065,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
if l != nil && l.c+q.c >= 2*kd { if l != nil && l.c+q.c >= 2*kd {
l.mvR(q, 1) l.mvR(q, 1)
p.x[pi-1].k = q.d[0].k p.x[pi-1].k = q.d[0].k
t.hitKmin.set(q.d[0].k) t.setHitKmin(q.d[0].k)
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
t.hitDi += 1 t.hitDi += 1
return return
...@@ -1060,7 +1074,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -1060,7 +1074,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
if r != nil && q.c+r.c >= 2*kd { if r != nil && q.c+r.c >= 2*kd {
q.mvL(r, 1) q.mvL(r, 1)
p.x[pi].k = r.d[0].k p.x[pi].k = r.d[0].k
t.hitKmax.set(r.d[0].k) t.setHitKmax(r.d[0].k)
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
// hitDi stays the same // hitDi stays the same
r.d[r.c] = zde // GC r.d[r.c] = zde // GC
...@@ -1073,13 +1087,14 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -1073,13 +1087,14 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
pi-- pi--
t.cat(p, l, q, pi) t.cat(p, l, q, pi)
t.hitKmin = t.hitPKmin t.hitKmin = t.hitPKmin
t.hitKminSet = t.hitPKminSet // XXX move vvv under else ? (but vs t.r == l)
if t.r == l { if t.r == l {
// cat removed p // cat removed p
t.hitP = nil t.hitP = nil
t.hitPi = -1 t.hitPi = -1
} else { } else {
if pi > 0 { // k=-∞ @-1 if pi > 0 { // k=-∞ @-1
t.hitKmin.set(p.x[pi-1].k) t.setHitKmin(p.x[pi-1].k)
} }
t.hitPi = pi t.hitPi = pi
} }
...@@ -1089,13 +1104,14 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -1089,13 +1104,14 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
t.cat(p, q, r, pi) t.cat(p, q, r, pi)
// hitD/hitDi stays unchanged // hitD/hitDi stays unchanged
t.hitKmax = t.hitPKmax t.hitKmax = t.hitPKmax
t.hitKmaxSet = t.hitPKmaxSet // XXX move vvv under else ? (but vs t.r == q)
if t.r == q { if t.r == q {
// cat removed p // cat removed p
t.hitP = nil t.hitP = nil
t.hitPi = -1 t.hitPi = -1
} else { } else {
if pi < p.c { // k=+∞ @p.c if pi < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} }
//t.hitPi = pi already pre-set this way //t.hitPi = pi already pre-set this way
} }
...@@ -1123,7 +1139,7 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -1123,7 +1139,7 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) {
i++ i++
l.c-- l.c--
p.x[pi-1].k = l.x[l.c].k p.x[pi-1].k = l.x[l.c].k
t.hitKmin.set(l.x[l.c].k) t.setHitKmin(l.x[l.c].k)
return q, i return q, i
} }
...@@ -1132,7 +1148,7 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -1132,7 +1148,7 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) {
q.c++ q.c++
q.x[q.c].ch = r.x[0].ch q.x[q.c].ch = r.x[0].ch
p.x[pi].k = r.x[0].k p.x[pi].k = r.x[0].k
t.hitKmax.set(r.x[0].k) t.setHitKmax(r.x[0].k)
copy(r.x[:], r.x[1:r.c]) copy(r.x[:], r.x[1:r.c])
r.c-- r.c--
rc := r.c rc := r.c
...@@ -1147,17 +1163,21 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -1147,17 +1163,21 @@ func (t *Tree) underflowX(p *x, q *x, pi int, i int) (*x, int) {
pi-- pi--
t.catX(p, l, q, pi) t.catX(p, l, q, pi)
q = l q = l
t.hitKmin = t.hitPKmin
if t.r != q && pi > 0 { // k=+∞ @p.c if t.r != q && pi > 0 { // k=+∞ @p.c
t.hitKmin.set(p.x[pi-1].k) t.setHitKmin(p.x[pi-1].k)
} else {
t.hitKmin = t.hitPKmin
t.hitKminSet = t.hitPKminSet
} }
return q, i return q, i
} }
t.catX(p, q, r, pi) t.catX(p, q, r, pi)
t.hitKmax = t.hitPKmax
if t.r != q && pi < p.c { // k=+∞ @p.c if t.r != q && pi < p.c { // k=+∞ @p.c
t.hitKmax.set(p.x[pi].k) t.setHitKmax(p.x[pi].k)
} else {
t.hitKmax = t.hitPKmax
t.hitKmaxSet = t.hitPKmaxSet
} }
return q, i return q, i
} }
......
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