From c6724ca71fc35fd8f23c62204a227ef573236a1a Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sun, 10 Oct 2021 06:03:34 -0500 Subject: [PATCH] Add an option to create MemDB iterators with no Mutex for the CacheKVStore (#187) * Add an option to create MemDB iterators with no Mutex for the CacheKVStore * Update changelog --- .gitignore | 3 ++- CHANGELOG.md | 4 ++++ memdb.go | 16 ++++++++++++++++ memdb_iterator.go | 14 ++++++++++++-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b3efc3918..ce205f69a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out -.idea \ No newline at end of file +.idea +vendor/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f667baa6..cb43176ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Pending + +* Add an option for creating a mem db with no mutex + ## 0.6.4 **2021-02-09** diff --git a/memdb.go b/memdb.go index 604e6a06e..d019af230 100644 --- a/memdb.go +++ b/memdb.go @@ -190,3 +190,19 @@ func (db *MemDB) ReverseIterator(start, end []byte) (Iterator, error) { } return newMemDBIterator(db, start, end, true), nil } + +// IteratorNoMtx makes an iterator with no mutex. +func (db *MemDB) IteratorNoMtx(start, end []byte) (Iterator, error) { + if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { + return nil, errKeyEmpty + } + return newMemDBIteratorMtxChoice(db, start, end, false, false), nil +} + +// ReverseIteratorNoMtx makes an iterator with no mutex. +func (db *MemDB) ReverseIteratorNoMtx(start, end []byte) (Iterator, error) { + if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { + return nil, errKeyEmpty + } + return newMemDBIteratorMtxChoice(db, start, end, true, false), nil +} diff --git a/memdb_iterator.go b/memdb_iterator.go index 2a61e3757..ebd104f67 100644 --- a/memdb_iterator.go +++ b/memdb_iterator.go @@ -21,12 +21,17 @@ type memDBIterator struct { item *item start []byte end []byte + useMtx bool } var _ Iterator = (*memDBIterator)(nil) // newMemDBIterator creates a new memDBIterator. func newMemDBIterator(db *MemDB, start []byte, end []byte, reverse bool) *memDBIterator { + return newMemDBIteratorMtxChoice(db, start, end, reverse, true) +} + +func newMemDBIteratorMtxChoice(db *MemDB, start []byte, end []byte, reverse bool, useMtx bool) *memDBIterator { ctx, cancel := context.WithCancel(context.Background()) ch := make(chan *item, chBufferSize) iter := &memDBIterator{ @@ -34,11 +39,16 @@ func newMemDBIterator(db *MemDB, start []byte, end []byte, reverse bool) *memDBI cancel: cancel, start: start, end: end, + useMtx: useMtx, } - db.mtx.RLock() + if useMtx { + db.mtx.RLock() + } go func() { - defer db.mtx.RUnlock() + if useMtx { + defer db.mtx.RUnlock() + } // Because we use [start, end) for reverse ranges, while btree uses (start, end], we need // the following variables to handle some reverse iteration conditions ourselves. var (