dgraph-io / badger

Fast key-value DB in Go.

Home Page:https://dgraph.io/badger

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG]: return odd keys bytes when scaning with prefix

francisoliverlee opened this issue · comments

What version of Badger are you using?

version: github.com/dgraph-io/badger/v4 v4.2.0

What version of Go are you using?

1.20

Have you tried reproducing the issue with the latest release?

No

What is the hardware spec (RAM, CPU, OS)?

macos m1 2022

What steps will reproduce the bug?

  • describe
    i find an odd thing and solve it, but not sure what happened, can anyone help ?
    when doing for loop, value in tmpKeys are correct, but when exec "return keys, err", values-in-return-keys are not the same with values-in-tmpKeys-in-for-loop.
    and values-in-return-keys are not exist in db.
    for example
    keyPrefix := "cluster#broker#name#@cluster-test-1@", and returns are as follows that not exist in db

    cluster#broker#name#@cluster-test@broker-test-890
    cluster#broker#name#@cluster-test@broker-test-9-1
    cluster#broker#name#@cluster-test@broker-test-9010
    cluster#broker#name#@cluster-test@broker-test-9111
    cluster#broker#name#@cluster-test@broker-test-922
    cluster#broker#name#@cluster-test@broker-test-933
    
  • wrong source code

    func (b badgerStore) KeysWithoutValues(bucket string, pattern []byte) (keys [][]byte, err error) {
    	b.logKey("KeysWithoutValues", pattern)
    	err = b.db.View(func(txn *badger.Txn) error {
    		it := txn.NewIterator(badger.IteratorOptions{
    			PrefetchValues: false,
    			PrefetchSize:   100,
    			Reverse:        false,
    			AllVersions:    false,
    		})
    		defer it.Close()
    		prefix := pattern
    
    		var tmpKeys [][]byte
    		for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
    			item := it.Item()
    			if item.IsDeletedOrExpired() {
    				continue
    			}
    			k := item.Key()
    			tmpKeys = append(tmpKeys, k)
    		}
    		keys = tmpKeys
    		return nil
    	})
    
    	return keys, err
    }

Expected behavior and actual result.

return right keys with prefix scaning

Additional information

  • solve it myself
    when return keys []byte, i change it to string as following codes, then get it right.
func (b badgerStore) KeyStringsWithoutValues(bucket string, pattern []byte) (keys []string, err error) {
	b.logKey("KeyStringsWithoutValues", pattern)
	err = b.db.View(func(txn *badger.Txn) error {
		it := txn.NewIterator(badger.IteratorOptions{
			PrefetchValues: false,
			PrefetchSize:   100,
			Reverse:        false,
			AllVersions:    false,
		})
		defer it.Close()
		for it.Seek(pattern); it.ValidForPrefix(pattern); it.Next() {
			item := it.Item()
			if item.IsDeletedOrExpired() {
				continue
			}
			k := item.Key()
			keys = append(keys, string(k))

		}
		return nil
	})

	return keys, err
}