Commit 0f0644ab authored by Kirill Smelkov's avatar Kirill Smelkov

example: Regenerate int.go + cherry-pick corresponding all_test.go updates

example/int.go receives updates from aaaa43c9 (Fix Prev() to behave like
Next() in reverse).

We have to also update example/all_test.go because otherwise tests stop
passing in example/ as the above commit changed both Prev and test
logic.

There are more missed updates to example/all_test.go - here I pick only
minimum to keep tests passing in example/ .
parent aaaa43c9
...@@ -620,13 +620,13 @@ func TestEnumeratorPrev(t *testing.T) { ...@@ -620,13 +620,13 @@ func TestEnumeratorPrev(t *testing.T) {
hit bool hit bool
keys []int keys []int
}{ }{
{5, false, []int{10}}, {5, false, []int{}},
{10, true, []int{10}}, {10, true, []int{10}},
{15, false, []int{20, 10}}, {15, false, []int{10}},
{20, true, []int{20, 10}}, {20, true, []int{20, 10}},
{25, false, []int{30, 20, 10}}, {25, false, []int{20, 10}},
{30, true, []int{30, 20, 10}}, {30, true, []int{30, 20, 10}},
{35, false, []int{}}, {35, false, []int{30, 20, 10}},
} }
for i, test := range table { for i, test := range table {
...@@ -683,6 +683,51 @@ func TestEnumeratorPrev(t *testing.T) { ...@@ -683,6 +683,51 @@ func TestEnumeratorPrev(t *testing.T) {
} }
} }
func TestEnumeratorPrevSanity(t *testing.T) {
// seeking within 3 keys: 10, 20, 30
table := []struct {
k int
hit bool
kOut int
vOut int
errOut error
}{
{10, true, 10, 100, nil},
{20, true, 20, 200, nil},
{30, true, 30, 300, nil},
{35, false, 30, 300, nil},
{25, false, 20, 200, nil},
{15, false, 10, 100, nil},
{5, false, 0, 0, io.EOF},
}
for i, test := range table {
r := TreeNew(cmp)
r.Set(10, 100)
r.Set(20, 200)
r.Set(30, 300)
en, hit := r.Seek(test.k)
if g, e := hit, test.hit; g != e {
t.Fatal(i, g, e)
}
k, v, err := en.Prev()
if g, e := err, test.errOut; g != e {
t.Fatal(i, g, e)
}
if g, e := k, test.kOut; g != e {
t.Fatal(i, g, e)
}
if g, e := v, test.vOut; g != e {
t.Fatal(i, g, e)
}
}
}
func BenchmarkSeekSeq1e3(b *testing.B) { func BenchmarkSeekSeq1e3(b *testing.B) {
benchmarkSeekSeq(b, 1e3) benchmarkSeekSeq(b, 1e3)
} }
......
...@@ -76,7 +76,7 @@ type ( ...@@ -76,7 +76,7 @@ type (
// //
// However, once an Enumerator returns io.EOF to signal "no more // However, once an Enumerator returns io.EOF to signal "no more
// items", it does no more attempt to "resync" on tree mutation(s). In // items", it does no more attempt to "resync" on tree mutation(s). In
// other words, io.EOF from an Enumaretor is "sticky" (idempotent). // other words, io.EOF from an Enumerator is "sticky" (idempotent).
Enumerator struct { Enumerator struct {
err error err error
hit bool hit bool
...@@ -450,7 +450,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { ...@@ -450,7 +450,7 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.ver++ t.ver++
l, r := p.siblings(pi) l, r := p.siblings(pi)
if l != nil && l.c < 2*kd { if l != nil && l.c < 2*kd && i != 0 {
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
...@@ -473,9 +473,9 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { ...@@ -473,9 +473,9 @@ func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.split(p, q, pi, i, k, v) t.split(p, q, pi, i, k, v)
} }
// Seek returns an Enumerator positioned on a an item such that k >= item's // Seek returns an Enumerator positioned on an item such that k >= item's key.
// key. ok reports if k == item.key The Enumerator's position is possibly // ok reports if k == item.key The Enumerator's position is possibly after the
// after the last item in the tree. // last item in the tree.
func (t *Tree) Seek(k int) (e *Enumerator, ok bool) { func (t *Tree) Seek(k int) (e *Enumerator, ok bool) {
q := t.r q := t.r
if q == nil { if q == nil {
...@@ -826,13 +826,7 @@ func (e *Enumerator) Next() (k int, v int, err error) { ...@@ -826,13 +826,7 @@ func (e *Enumerator) Next() (k int, v int, err error) {
} }
if e.ver != e.t.ver { if e.ver != e.t.ver {
f, hit := e.t.Seek(e.k) f, _ := e.t.Seek(e.k)
if !e.hit && hit {
if err = f.next(); err != nil {
return
}
}
*e = *f *e = *f
f.Close() f.Close()
} }
...@@ -849,7 +843,7 @@ func (e *Enumerator) Next() (k int, v int, err error) { ...@@ -849,7 +843,7 @@ func (e *Enumerator) Next() (k int, v int, err error) {
i := e.q.d[e.i] i := e.q.d[e.i]
k, v = i.k, i.v k, v = i.k, i.v
e.k, e.hit = k, false e.k, e.hit = k, true
e.next() e.next()
return return
} }
...@@ -880,13 +874,7 @@ func (e *Enumerator) Prev() (k int, v int, err error) { ...@@ -880,13 +874,7 @@ func (e *Enumerator) Prev() (k int, v int, err error) {
} }
if e.ver != e.t.ver { if e.ver != e.t.ver {
f, hit := e.t.Seek(e.k) f, _ := e.t.Seek(e.k)
if !e.hit && hit {
if err = f.prev(); err != nil {
return
}
}
*e = *f *e = *f
f.Close() f.Close()
} }
...@@ -895,15 +883,22 @@ func (e *Enumerator) Prev() (k int, v int, err error) { ...@@ -895,15 +883,22 @@ func (e *Enumerator) Prev() (k int, v int, err error) {
return return
} }
if !e.hit {
// move to previous because Seek overshoots if there's no hit
if err = e.prev(); err != nil {
return
}
}
if e.i >= e.q.c { if e.i >= e.q.c {
if err = e.next(); err != nil { if err = e.prev(); err != nil {
return return
} }
} }
i := e.q.d[e.i] i := e.q.d[e.i]
k, v = i.k, i.v k, v = i.k, i.v
e.k, e.hit = k, false e.k, e.hit = k, true
e.prev() e.prev()
return return
} }
......
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