I’m trying to iterate over the db and basically get something after a certain point, but failing miserably. Follow me here for a moment.
If I do this:
package repository
import (
"encoding/binary"
"fmt"
"github.com/dgraph-io/badger/v3"
"testing"
)
func TestBadger(t *testing.T) {
badgerOptions := badger.DefaultOptions("")
badgerOptions.InMemory = true
db, _ := badger.Open(badgerOptions)
defer db.Close()
db.Update(func(txn *badger.Txn) error {
return txn.Set(key([]byte("abc"), "myid", 40, 1000), []byte("abc"))
})
db.Update(func(txn *badger.Txn) error {
return txn.Set(key([]byte("abc"), "myid", 40, 500), []byte("abc"))
})
db.Update(func(txn *badger.Txn) error {
return txn.Set(key([]byte("abc"), "myid", 40, 2000), []byte("abc"))
})
db.Update(func(txn *badger.Txn) error {
return txn.Set(key([]byte("abc"), "myid", 40, 3000), []byte("abc"))
})
db.View(func(txn *badger.Txn) error {
validPrefix := append([]byte("abc"), "|hello|"...)
opt := badger.DefaultIteratorOptions
opt.Prefix = validPrefix
it := txn.NewIterator(opt)
defer it.Close()
for it.Seek(nil); it.ValidForPrefix(validPrefix); it.Next() {
item := it.Item()
err := item.Value(func(v []byte) error {
fmt.Println(parseKey(item.Key()))
return nil
})
if err != nil {
panic(err)
}
}
return nil
})
}
func key(script []byte, id string, out uint64, height uint32) []byte {
firstPart := append(script, "|hello|"...)
secondPart := make([]byte, 4)
binary.LittleEndian.PutUint32(secondPart, height)
thirdPart := []byte(fmt.Sprintf("|%s|%d", id, out))
key := append(firstPart, secondPart...)
key = append(key, thirdPart...)
return key
}
func parseKey(key []byte) string {
script := key[:3]
hello := key[3:10]
height := binary.LittleEndian.Uint32(key[10:14])
id := key[14:20]
out := key[20:23]
return fmt.Sprintf("%s%s%d%s%s\n", script, hello, height, id, out)
}
I get this:
abc|hello|3000|myid|40
abc|hello|2000|myid|40
abc|hello|1000|myid|40
abc|hello|500|myid|40
I was expecting to get in the order 500, 1000, 2000, 3000 in order, or at least on the order that I added? (1000, 500, 2000, 3000).
I tried some different strategies.
If I add opt.Reverse = true
then I get nothing from the iterator.
If I try to use this:
height := make([]byte, 4)
binary.LittleEndian.PutUint32(height, 1000)
for it.Seek(append(validPrefix, height...)); it.ValidForPrefix(validPrefix); it.Next() {
I get this:
abc|hello|1000|myid|40
abc|hello|500|myid|40
Wait, I haven’t finished my attempts yet, if I do this:
opt.Reverse = true
height := make([]byte, 4)
binary.LittleEndian.PutUint32(height, 1000)
for it.Seek(append(validPrefix, height...)); it.ValidForPrefix(validPrefix); it.Next() {
Then I get this, which looks amazing:
abc|hello|2000|myid|40
abc|hello|3000|myid|40
Which kind make sense again, I’m reversing the order that was there, but then if I do this (height 1):
opt.Reverse = true
height := make([]byte, 4)
binary.LittleEndian.PutUint32(height, 1)
for it.Seek(append(validPrefix, height...)); it.ValidForPrefix(validPrefix); it.Next() {
Then I get nothing.
It’s mind blow
Is there a way to get something in order or after a certain point?
Thanks