Code:
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"github.com/dgraph-io/badger"
)
func main() {
dir, err := ioutil.TempDir("", "badger")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(dir)
opts := badger.DefaultOptions
opts.Dir = dir
opts.ValueDir = dir
db, err := badger.Open(opts)
if err != nil {
log.Fatal(err)
}
defer db.Close()
bkey := func(i int) []byte {
return []byte(fmt.Sprintf("%09d", i))
}
bval := func(i int) []byte {
return []byte(fmt.Sprintf("%025d", i))
}
txn := db.NewTransaction(true)
// Fill in 1000 items
n := 1000
for i := 0; i < n; i++ {
err := txn.Set(bkey(i), bval(i))
if err != nil {
log.Fatal(err)
}
}
err = txn.Commit(nil)
if err != nil {
log.Fatal(err)
}
opt := badger.DefaultIteratorOptions
opt.PrefetchSize = 10
opt.Reverse = true
// Iterate over 1000 items
var count int
err = db.View(func(txn *badger.Txn) error {
it := txn.NewIterator(opt)
for it.Seek([]byte("0")); it.ValidForPrefix([]byte("0")); it.Next() {
count++
}
return nil
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Counted %d elements", count)
}
This code returns 0 elements in reverse mode and 1000 elements with reverse = false
@brk0v That's the expected behaviour. Seek searches for a key greater than or equal to the specifed key. Say you have the following keys "00" ,"01", "02". When you seek for "01" in reverse mode the iteration would start at "00".
Similarly in your case since you are seeking for "0" it will go past all the values and you won't find anything.
Ok. Got it.
My case is to emulate some kind of buckets inside badger db. I was adding a prefix to keys. This prefix is a bucket. But with current iterator logic I can't find the last item in my "bucket".
You still can. You just need to choose the seek key wisely. Following from @janardhan1993's example, if you have [00, 01, 02], and you want to start from 01, then you can use 01~ (with tilde character). That way, the seek would stop just before 01, and it the first item would be 01.
He wanted to get the last item in the bucket, not the first, @manishrjain - I think, you misunderstood his statement.
Getting the reverse latest data from badgerdb is still Pain IA.
It's all about the choice of seek key. If you want the first data from reverse, you can just call Rewind after setting Reverse option.
There is no way to seek reverse and rewind based on prefix.
You can set reverse and then Seek to prefix + 0xFF byte. That'd bring you to prefix.
Most helpful comment
You can set reverse and then Seek to prefix + 0xFF byte. That'd bring you to prefix.