Commit d98ed0e1 authored by Kirill Smelkov's avatar Kirill Smelkov

X goodbye xkey

Reworked hitK* and associated set flags to liveseparately not to create
holes.
parent 8b1f6c22
...@@ -155,6 +155,32 @@ func opPut(written bool) treeOp { ...@@ -155,6 +155,32 @@ func opPut(written bool) treeOp {
return opGet return opGet
} }
func xeq(k1, k2 interface{} /*K*/, k1set, k2set bool) bool {
if k1set != k2set {
return false
}
if !k1set {
return true
}
return k1 == k2
}
func minStr(k interface{} /*K*/, kset bool) string {
s := fmt.Sprintf("%v", k)
if !kset {
s = fmt.Sprintf("-∞ /* %s */", s)
}
return s
}
func maxStr(k interface{} /*K*/, kset bool) string {
s := fmt.Sprintf("%v", k)
if !kset {
s = fmt.Sprintf("+∞ /* %s */", s)
}
return s
}
// checkHit rescans t from root and checks that hit D, P, Kmin/Kmax and rest all match what they should // checkHit rescans t from root and checks that hit D, P, Kmin/Kmax and rest all match what they should
// it can be used after Set/Put/Delete to verify that all hit parameters were calculated correctly // it can be used after Set/Put/Delete to verify that all hit parameters were calculated correctly
func (t *Tree) checkHit(k interface{} /*K*/, op treeOp) { func (t *Tree) checkHit(k interface{} /*K*/, op treeOp) {
...@@ -170,8 +196,10 @@ func (t *Tree) checkHit(k interface{} /*K*/, op treeOp) { ...@@ -170,8 +196,10 @@ func (t *Tree) checkHit(k interface{} /*K*/, op treeOp) {
i, pi := -1, -1 i, pi := -1, -1
var ok bool var ok bool
var hitKmin, hitKmax xkey var hitKmin, hitKmax interface {} /*K*/
var hitPKmin, hitPKmax xkey var hitPKmin, hitPKmax interface {} /*K*/
var hitKminSet, hitKmaxSet bool
var hitPKminSet, hitPKmaxSet bool
loop: loop:
// here the tree is immutable while we are rescanning it, which means // here the tree is immutable while we are rescanning it, which means
...@@ -188,6 +216,8 @@ loop: ...@@ -188,6 +216,8 @@ loop:
case *x: case *x:
hitPKmin = hitKmin hitPKmin = hitKmin
hitPKmax = hitKmax hitPKmax = hitKmax
hitPKminSet = hitKminSet
hitPKmaxSet = hitKmaxSet
if ok { if ok {
i++ i++
...@@ -198,18 +228,20 @@ loop: ...@@ -198,18 +228,20 @@ loop:
q = p.x[pi].ch q = p.x[pi].ch
if pi > 0 { if pi > 0 {
hitKmin.set(p.x[pi-1].k) hitKmin = p.x[pi-1].k
hitKminSet = true
if hitPKmin.kset && t.cmp(hitKmin.k, hitPKmin.k) <= 0 { if hitPKminSet && t.cmp(hitKmin, hitPKmin) <= 0 {
bad("hitKmin not ↑: %v -> %v", hitPKmin.k, hitKmin.k) bad("hitKmin not ↑: %v -> %v", hitPKmin, hitKmin)
} }
} }
if pi < p.c { // pi = p.c means k = ∞ if pi < p.c { // pi = p.c means k = ∞
hitKmax.set(p.x[pi].k) hitKmax = p.x[pi].k
hitKmaxSet = true
if hitPKmax.kset && t.cmp(hitKmax.k, hitPKmax.k) >= 0 { if hitPKmaxSet && t.cmp(hitKmax, hitPKmax) >= 0 {
bad("hitKmax not ↓: %v -> %v", hitPKmax.k, hitKmax.k) bad("hitKmax not ↓: %v -> %v", hitPKmax, hitKmax)
} }
} }
...@@ -242,19 +274,23 @@ loop: ...@@ -242,19 +274,23 @@ loop:
} }
} }
if !(hitKmin == t.hitKmin && hitKmax == t.hitKmax) { if !(xeq(t.hitKmin, hitKmin, t.hitKminSet, hitKminSet) && xeq(t.hitKmax, hitKmax, t.hitKmaxSet, hitKmaxSet)) {
bad("hitK mismatch: [%v, %v) ; want [%v, %v)", t.hitKmin, t.hitKmax, hitKmin, hitKmax) bad("hitK mismatch: [%v, %v) ; want [%v, %v)",
minStr(t.hitKmin, t.hitKminSet), maxStr(t.hitKmax, t.hitKmaxSet),
minStr(hitKmin, hitKminSet), maxStr(hitKmax, hitKmaxSet))
} }
if !(hitPKmin == t.hitPKmin && hitPKmax == t.hitPKmax) { if !(xeq(t.hitPKmin, hitPKmin, t.hitPKminSet, hitPKminSet) && xeq(t.hitPKmax, hitPKmax, t.hitPKmaxSet, hitPKmaxSet)) {
bad("hitPK mismatch: [%v, %v) ; want [%v, %v)", t.hitPKmin, t.hitPKmax, hitPKmin, hitPKmax) bad("hitPK mismatch: [%v, %v) ; want [%v, %v)",
minStr(t.hitPKmin, t.hitPKminSet), maxStr(t.hitPKmax, t.hitPKmaxSet),
minStr(hitPKmin, hitPKminSet), maxStr(hitPKmax, hitPKmaxSet))
} }
if !(dd == t.hitD && i == t.hitDi) { if !(t.hitD == dd && t.hitDi == i) {
bad("hitD mismatch: %v @%d ; want %v @%d", t.hitD, t.hitDi, dd, i) bad("hitD mismatch: %v @%d ; want %v @%d", t.hitD, t.hitDi, dd, i)
} }
if !(p == t.hitP && pi == t.hitPi) { if !(t.hitP == p && t.hitPi == pi) {
bad("hitP mismatch: %v @%d ; want %v @%d", t.hitP, t.hitPi, p, pi) bad("hitP mismatch: %v @%d ; want %v @%d", t.hitP, t.hitPi, p, pi)
} }
......
...@@ -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() {
...@@ -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 interface{} /*K*/ // hitD allowed key range is [hitKmin, hitKmax)
hitPKmin xkey // ----//--- for hitP hitKmax interface{} /*K*/
hitPKmax xkey hitPKmin interface{} /*K*/ // ----//--- for hitP
hitPKmax interface{} /*K*/
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 interface{} /*K*/
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 interface{} /*K*/) { func (t *Tree) setHitKmin(k interface{} /*K*/) { t.hitKmin = k; t.hitKminSet = true }
xk.k = k func (t *Tree) setHitKmax(k interface{} /*K*/) { t.hitKmax = k; t.hitKmaxSet = true }
xk.kset = true func (t *Tree) setHitPKmin(k interface{} /*K*/) { t.hitPKmin = k; t.hitPKminSet = true }
} func (t *Tree) setHitPKmax(k interface{} /*K*/) { 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++
} }
...@@ -309,7 +311,7 @@ func (t *Tree) catX(p, q, r *x, pi int) { ...@@ -309,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())
//}() //}()
...@@ -372,8 +374,8 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { ...@@ -372,8 +374,8 @@ func (t *Tree) Delete(k interface{} /*K*/) (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 interface{} /*K*/) (ok bool) { ...@@ -390,17 +392,19 @@ func (t *Tree) Delete(k interface{} /*K*/) (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 interface{} /*K*/) (i int, ok bool) { ...@@ -528,7 +532,7 @@ func (t *Tree) hitFind(k interface{} /*K*/) (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 interface{} /*K*/) (i int, ok bool) { ...@@ -537,7 +541,7 @@ func (t *Tree) hitFind(k interface{} /*K*/) (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 interface{} /*K*/, v interface{ ...@@ -626,7 +630,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{
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 interface{} /*K*/, v interface{ ...@@ -636,7 +640,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{
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 interface{} /*K*/, v interface{ ...@@ -644,10 +648,12 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{
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
...@@ -712,7 +718,7 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) { ...@@ -712,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())
//}() //}()
...@@ -757,8 +763,8 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -757,8 +763,8 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
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 interface{} /*K*/, v interface{} /*V*/) { ...@@ -775,17 +781,19 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
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:
...@@ -824,7 +832,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -824,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
...@@ -895,8 +903,8 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists ...@@ -895,8 +903,8 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists
} }
// 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 interface{} /*K*/, upd func(oldV interface{} /*V*/, exists ...@@ -913,17 +921,19 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists
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 interface{} /*K*/, v interface{} / ...@@ -998,15 +1008,17 @@ func (t *Tree) split(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /
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