From 191cc4503254691343061c953e6632e41bf0ac7e Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 24 Sep 2021 16:00:13 +0300 Subject: [PATCH] core: sort items in MemoryStore.Seek MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MemoryStore is used in a MemCachedStore as a persistent layer in tests. Further commits suppose that persistent storage returns sorted values from Seek, so sort the result of MemoryStore.Seek. Benchmark results for 10000 matching items in MemoryStore compared to master: name old time/op new time/op delta MemorySeek-8 712µs ± 0% 3850µs ± 0% +440.52% (p=0.000 n=8+8) name old alloc/op new alloc/op delta MemorySeek-8 160kB ± 0% 2724kB ± 0% +1602.61% (p=0.000 n=10+8) name old allocs/op new allocs/op delta MemorySeek-8 10.0k ± 0% 10.0k ± 0% +0.24% (p=0.000 n=10+10) For details on implementation efficiency see the https://github.com/nspcc-dev/neo-go/pull/2193#discussion_r722993358. --- pkg/core/storage/memory_store.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/core/storage/memory_store.go b/pkg/core/storage/memory_store.go index 45c4ae9fd..21ca47645 100644 --- a/pkg/core/storage/memory_store.go +++ b/pkg/core/storage/memory_store.go @@ -1,6 +1,8 @@ package storage import ( + "bytes" + "sort" "strings" "sync" @@ -128,11 +130,21 @@ func (s *MemoryStore) SeekAll(key []byte, f func(k, v []byte)) { // seek is an internal unlocked implementation of Seek. func (s *MemoryStore) seek(key []byte, f func(k, v []byte)) { sk := string(key) + var memList []KeyValue for k, v := range s.mem { if strings.HasPrefix(k, sk) { - f([]byte(k), v) + memList = append(memList, KeyValue{ + Key: []byte(k), + Value: v, + }) } } + sort.Slice(memList, func(i, j int) bool { + return bytes.Compare(memList[i].Key, memList[j].Key) < 0 + }) + for _, kv := range memList { + f(kv.Key, kv.Value) + } } // Batch implements the Batch interface and returns a compatible Batch.