Skip to content

Commit

Permalink
fix: fix reverse iterator broken by seek (#2109)
Browse files Browse the repository at this point in the history
Fixes #2108
  • Loading branch information
harshil-goel committed Sep 12, 2024
1 parent d114b10 commit b77f2e8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
38 changes: 38 additions & 0 deletions db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,44 @@ func runBadgerTest(t *testing.T, opts *Options, test func(t *testing.T, db *DB))
test(t, db)
}

func TestReverseIterator(t *testing.T) {
runBadgerTest(t, nil, func(t *testing.T, db *DB) {
key := make([]byte, 6)
err := db.Update(func(txn *Txn) error {
binary.BigEndian.PutUint16(key, 5)
binary.BigEndian.PutUint32(key[2:], 1)
err1 := txn.Set(key, []byte("value1"))
require.NoError(t, err1)

binary.BigEndian.PutUint32(key[2:], 2)
err1 = txn.Set(key, []byte("value2"))
require.NoError(t, err1)
return nil
})

require.NoError(t, err)

err = db.View(func(txn *Txn) error {
searchBuffer := make([]byte, 3)
binary.BigEndian.PutUint16(searchBuffer, 5)
searchBuffer[2] = 0xFF

iteratorOptions := DefaultIteratorOptions
iteratorOptions.Reverse = true
iteratorOptions.PrefetchValues = false
iteratorOptions.Prefix = searchBuffer
it := txn.NewIterator(iteratorOptions)
defer it.Close()

it.Rewind()
require.Equal(t, it.Item().Key(), key)
return nil
})

require.NoError(t, err)
})
}

func TestWrite(t *testing.T) {
runBadgerTest(t, nil, func(t *testing.T, db *DB) {
for i := 0; i < 100; i++ {
Expand Down
12 changes: 7 additions & 5 deletions iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ func (it *Iterator) Next() {

// Set next item to current
it.item = it.data.pop()
for it.iitr.Valid() && hasPrefix(it.iitr, it.opt.Prefix) {
for it.iitr.Valid() && hasPrefix(it) {
if it.parseItem() {
// parseItem calls one extra next.
// This is used to deal with the complexity of reverse iteration.
Expand Down Expand Up @@ -725,9 +725,11 @@ func (it *Iterator) fill(item *Item) {
}
}

func hasPrefix(it y.Iterator, prefix []byte) bool {
if len(prefix) > 0 {
return bytes.HasPrefix(y.ParseKey(it.Key()), prefix)
func hasPrefix(it *Iterator) bool {
// We shouldn't check prefix in case the iterator is going in reverse. Since in reverse we expect
// people to append items to the end of prefix.
if !it.opt.Reverse && len(it.opt.Prefix) > 0 {
return bytes.HasPrefix(y.ParseKey(it.iitr.Key()), it.opt.Prefix)
}
return true
}
Expand All @@ -741,7 +743,7 @@ func (it *Iterator) prefetch() {
i := it.iitr
var count int
it.item = nil
for i.Valid() && hasPrefix(i, it.opt.Prefix) {
for i.Valid() && hasPrefix(it) {
if !it.parseItem() {
continue
}
Expand Down

0 comments on commit b77f2e8

Please sign in to comment.