sgarg
(Saurabh Garg)
March 19, 2018, 11:20pm
1
I am using prefixes in my keys. And I am able to lookup up data for those prefixes.
However, when I set opts.Reverse = true, I get no results. What is the recommended way of doing a reverse scan of prefixed keys?
My current code looks like this:
opts := badger.DefaultIteratorOptions
//opts.Reverse = true
it := txn.NewIterator(opts)
defer it.Close()
prefix := byte(req.Topic)
for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
}
Thanks!
mrjn
(Manish R Jain)
March 20, 2018, 7:22pm
2
You might be going past the search space. See:
opened 11:42PM - 09 Mar 18 UTC
closed 08:17PM - 12 Mar 18 UTC
kind/question
Code:
```go
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
opened 11:56PM - 10 Dec 17 UTC
closed 01:33PM - 11 Dec 17 UTC
kind/question
I am trying to Iterate in Reverse Order, but every time, I set `Reverse` to `tru… e`. It gives empty value.
Below is code -
```
txn := db.NewTransaction(false)
defer txn.Discard()
err = db.View(func(txn *badger.Txn) error {
DefaultIteratorOptions := badger.DefaultIteratorOptions
DefaultIteratorOptions.Reverse = true
it = txn.NewIterator(DefaultIteratorOptions)
key := strconv.Itoa(t.Year()) + "-" + strconv.Itoa(int(t.Month())) + "-" + strconv.Itoa(int(t.Day()))
prefix := []byte(key)
for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
item := it.Item()
k := item.Key()
v, err := item.ValueCopy([]byte(k))
if err != nil {
ctx.WriteString("Content not available")
return err
}
blogList, err := decodeBlog(v)
if err != nil {
fmt.Println("Error: decode: " + err.Error())
}
buffer.WriteString("My Content First")
}
})
```
sgarg
(Saurabh Garg)
March 20, 2018, 11:11pm
3
Thanks! Is there another way of breaking up the storage space?
Let’s say, I am storing data which has 1000 prefixes with 100 values each. To find 100 values for a given prefix, in the worst case, I am scanning through 100000 values. Instead, it would be nice to break-up the keyspace for prefixes.
mrjn
(Manish R Jain)
March 22, 2018, 11:20am
4
I’m not sure I follow the question. By “finding a value”, do you mean “seeking a key”? If so, a Seek would practically do a binary search in the entire space, it won’t scan over all the values.
If by finding a value, you really meant retrieve each value and compare it, even then you can seek to the prefix keyspace, and then do KV iteration.
sgarg
(Saurabh Garg)
March 22, 2018, 10:04pm
5
Never mind. I misunderstood how storage is being done.
system
(system)
Closed
April 21, 2018, 10:05pm
6
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.