Commit 15a07c50 authored by Kirill Smelkov's avatar Kirill Smelkov

Simplify "splitX bug" fix

We are simplyfing commit 5c732b36 (Fix splitX bug.) here:

By always passing to splitX i of index entry that is actually going to
be used for traversal(*) we don't need to consider edge cases, such as
when to move to next slot, inside splitX itself and this way there is no
need to keep relookup logic there.

So inside splitX it becomes very simple:

	- i <= kx  -> go left
	- i > kx   -> go right

The logic to advance i by 1 on exact key hits was already there in Set
and Put so it is natural for them to pass correct slot index to splitX.

(*) i.e. index of next slot on exact index entry key hit - see previous
    patch for explanation
parent 2a93ae07
...@@ -547,12 +547,13 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -547,12 +547,13 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if ok { if ok {
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
i++
if x.c > 2*kx { if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i) x, i = t.splitX(p, x, pi, i)
} }
pi = i + 1 pi = i
p = x p = x
q = x.x[i+1].ch q = x.x[i].ch
continue continue
case *d: case *d:
x.d[i].v = v x.d[i].v = v
...@@ -614,12 +615,13 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists ...@@ -614,12 +615,13 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists
if ok { if ok {
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
i++
if x.c > 2*kx { if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i) x, i = t.splitX(p, x, pi, i)
} }
pi = i + 1 pi = i
p = x p = x
q = x.x[i+1].ch q = x.x[i].ch
continue continue
case *d: case *d:
oldV = x.d[i].v oldV = x.d[i].v
...@@ -701,36 +703,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -701,36 +703,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) {
r.c = kx r.c = kx
if pi >= 0 { if pi >= 0 {
p.insert(pi, q.x[kx].k, r) p.insert(pi, q.x[kx].k, r)
q.x[kx].k = zk } else {
for i := range q.x[kx+1:] { t.r = newX(q).insert(0, q.x[kx].k, r)
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return p, pi
default: // i > kx
return r, i - kx - 1
}
} }
nr := newX(q).insert(0, q.x[kx].k, r)
t.r = nr
q.x[kx].k = zk q.x[kx].k = zk
for i := range q.x[kx+1:] { for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe q.x[kx+i+1] = zxe
} }
if i > kx {
switch { q = r
case i < kx: i -= kx + 1
return q, i
case i == kx:
return nr, 0
default: // i > kx
return r, i - kx - 1
} }
return q, i
} }
func (t *Tree) underflow(p *x, q *d, pi int) { func (t *Tree) underflow(p *x, q *d, pi int) {
......
...@@ -547,12 +547,13 @@ func (t *Tree) Set(k int, v int) { ...@@ -547,12 +547,13 @@ func (t *Tree) Set(k int, v int) {
if ok { if ok {
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
i++
if x.c > 2*kx { if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i) x, i = t.splitX(p, x, pi, i)
} }
pi = i + 1 pi = i
p = x p = x
q = x.x[i+1].ch q = x.x[i].ch
continue continue
case *d: case *d:
x.d[i].v = v x.d[i].v = v
...@@ -614,12 +615,13 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool) ...@@ -614,12 +615,13 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool)
if ok { if ok {
switch x := q.(type) { switch x := q.(type) {
case *x: case *x:
i++
if x.c > 2*kx { if x.c > 2*kx {
x, i = t.splitX(p, x, pi, i) x, i = t.splitX(p, x, pi, i)
} }
pi = i + 1 pi = i
p = x p = x
q = x.x[i+1].ch q = x.x[i].ch
continue continue
case *d: case *d:
oldV = x.d[i].v oldV = x.d[i].v
...@@ -701,36 +703,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) { ...@@ -701,36 +703,20 @@ func (t *Tree) splitX(p *x, q *x, pi int, i int) (*x, int) {
r.c = kx r.c = kx
if pi >= 0 { if pi >= 0 {
p.insert(pi, q.x[kx].k, r) p.insert(pi, q.x[kx].k, r)
q.x[kx].k = zk } else {
for i := range q.x[kx+1:] { t.r = newX(q).insert(0, q.x[kx].k, r)
q.x[kx+i+1] = zxe
}
switch {
case i < kx:
return q, i
case i == kx:
return p, pi
default: // i > kx
return r, i - kx - 1
}
} }
nr := newX(q).insert(0, q.x[kx].k, r)
t.r = nr
q.x[kx].k = zk q.x[kx].k = zk
for i := range q.x[kx+1:] { for i := range q.x[kx+1:] {
q.x[kx+i+1] = zxe q.x[kx+i+1] = zxe
} }
if i > kx {
switch { q = r
case i < kx: i -= kx + 1
return q, i
case i == kx:
return nr, 0
default: // i > kx
return r, i - kx - 1
} }
return q, i
} }
func (t *Tree) underflow(p *x, q *d, pi int) { func (t *Tree) underflow(p *x, q *d, pi int) {
......
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