From 5efabb67d2136dfb5414bc9ec4b5ec8ed713df5e Mon Sep 17 00:00:00 2001 From: egonspace Date: Thu, 25 Nov 2021 17:45:30 +0900 Subject: [PATCH 1/2] fix: should use copied value of iterator --- rocksdb/db.go | 6 +++++- rocksdb/iterator.go | 40 +++++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/rocksdb/db.go b/rocksdb/db.go index d0afedf..01e8911 100644 --- a/rocksdb/db.go +++ b/rocksdb/db.go @@ -69,7 +69,11 @@ func (db *RocksDB) Get(key []byte) ([]byte, error) { if len(key) == 0 { return nil, tmdb.ErrKeyEmpty } - return db.db.GetBytes(db.ro, key) + res, err := db.db.Get(db.ro, key) + if err != nil { + return nil, err + } + return moveSliceToBytes(res), nil } // Has implements DB. diff --git a/rocksdb/iterator.go b/rocksdb/iterator.go index cd555fb..9742b31 100644 --- a/rocksdb/iterator.go +++ b/rocksdb/iterator.go @@ -3,6 +3,7 @@ package rocksdb import ( "github.com/line/gorocksdb" tmdb "github.com/line/tm-db/v2" + "github.com/line/tm-db/v2/internal/util" ) type rocksDBIterator struct { @@ -10,8 +11,8 @@ type rocksDBIterator struct { opts *gorocksdb.ReadOptions isReverse bool isInvalid bool - key *gorocksdb.Slice - value *gorocksdb.Slice + key []byte + value []byte } var _ tmdb.Iterator = (*rocksDBIterator)(nil) @@ -69,25 +70,26 @@ func (itr *rocksDBIterator) invalidate() { func (itr *rocksDBIterator) Key() []byte { itr.assertIsValid() if itr.key == nil { - itr.key = itr.source.Key() + itr.key = moveSliceToBytes(itr.source.Key()) } - return itr.key.Data() + return itr.key } // Value implements Iterator. func (itr *rocksDBIterator) Value() []byte { itr.assertIsValid() if itr.value == nil { - itr.value = itr.source.Value() + itr.value = moveSliceToBytes(itr.source.Value()) } - return itr.value.Data() + return itr.value } // Next implements Iterator. func (itr *rocksDBIterator) Next() { itr.assertIsValid() - itr.freeKeyValue() + itr.key = nil + itr.value = nil if !itr.isReverse { itr.source.Next() @@ -111,23 +113,23 @@ func (itr *rocksDBIterator) Close() error { itr.opts.Destroy() itr.opts = nil } - itr.freeKeyValue() return nil } -func (itr *rocksDBIterator) freeKeyValue() { - if itr.key != nil { - itr.key.Free() - itr.key = nil - } - if itr.value != nil { - itr.value.Free() - itr.value = nil - } -} - func (itr *rocksDBIterator) assertIsValid() { if itr.isInvalid { panic("iterator is invalid") } } + +// moveSliceToBytes will free the slice and copy out a go []byte +// This function can be applied on *Slice returned from Key() and Value() +// of an Iterator, because they are marked as freed. +func moveSliceToBytes(s *gorocksdb.Slice) []byte { + var bz []byte + if s.Exists() { + bz = util.Cp(s.Data()) + } + s.Free() + return bz +} From 1e7416d71922e148a76a89ca47b822e63bfa4710 Mon Sep 17 00:00:00 2001 From: egonspace Date: Tue, 30 Nov 2021 11:34:04 +0900 Subject: [PATCH 2/2] fix: apply comment --- rocksdb/db.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rocksdb/db.go b/rocksdb/db.go index 01e8911..d0afedf 100644 --- a/rocksdb/db.go +++ b/rocksdb/db.go @@ -69,11 +69,7 @@ func (db *RocksDB) Get(key []byte) ([]byte, error) { if len(key) == 0 { return nil, tmdb.ErrKeyEmpty } - res, err := db.db.Get(db.ro, key) - if err != nil { - return nil, err - } - return moveSliceToBytes(res), nil + return db.db.GetBytes(db.ro, key) } // Has implements DB.