Badger: Seek iterator with Reverse doesn't work

Created on 10 Mar 2018  路  7Comments  路  Source: dgraph-io/badger

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

kinquestion

Most helpful comment

You can set reverse and then Seek to prefix + 0xFF byte. That'd bring you to prefix.

All 7 comments

@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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tonyalaribe picture tonyalaribe  路  8Comments

deepakjois picture deepakjois  路  7Comments

jackmiller334 picture jackmiller334  路  7Comments

vrealzhou picture vrealzhou  路  4Comments

JeanMertz picture JeanMertz  路  7Comments