From 0a894db7f8c9988865b88f07f661878305ad3f7d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 7 Feb 2020 15:08:25 +0300 Subject: [PATCH] storage: add Exists flag to KeyValue in batch Set Exists flag if an item with the specified key was already present in storage before persisting. --- cli/server/dump.go | 9 +++++++-- pkg/core/storage/memcached_store.go | 10 ++++++++-- pkg/core/storage/memcached_store_test.go | 8 ++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/cli/server/dump.go b/cli/server/dump.go index 5e6ac009a..37865d3ab 100644 --- a/cli/server/dump.go +++ b/cli/server/dump.go @@ -68,9 +68,14 @@ func batchToMap(index uint32, batch *storage.MemBatch) map[string]interface{} { continue } + op := "Added" + if batch.Put[i].Exists { + op = "Changed" + } + key = toNeoStorageKey(key[1:]) ops = append(ops, storageOp{ - State: "Added", + State: op, Key: hex.EncodeToString(key), Value: "00" + hex.EncodeToString(batch.Put[i].Value), }) @@ -78,7 +83,7 @@ func batchToMap(index uint32, batch *storage.MemBatch) map[string]interface{} { for i := range batch.Deleted { key := batch.Deleted[i].Key - if len(key) == 0 || key[0] != byte(storage.STStorage) { + if len(key) == 0 || key[0] != byte(storage.STStorage) || !batch.Deleted[i].Exists { continue } diff --git a/pkg/core/storage/memcached_store.go b/pkg/core/storage/memcached_store.go index bc99393eb..fc5daba3b 100644 --- a/pkg/core/storage/memcached_store.go +++ b/pkg/core/storage/memcached_store.go @@ -14,6 +14,8 @@ type ( KeyValue struct { Key []byte Value []byte + + Exists bool } // MemBatch represents a changeset to be persisted. @@ -54,12 +56,16 @@ func (s *MemCachedStore) GetBatch() *MemBatch { b.Put = make([]KeyValue, 0, len(s.mem)) for k, v := range s.mem { - b.Put = append(b.Put, KeyValue{Key: []byte(k), Value: v}) + key := []byte(k) + _, err := s.ps.Get(key) + b.Put = append(b.Put, KeyValue{Key: key, Value: v, Exists: err == nil}) } b.Deleted = make([]KeyValue, 0, len(s.del)) for k := range s.del { - b.Deleted = append(b.Deleted, KeyValue{Key: []byte(k)}) + key := []byte(k) + _, err := s.ps.Get(key) + b.Deleted = append(b.Deleted, KeyValue{Key: key, Exists: err == nil}) } return &b diff --git a/pkg/core/storage/memcached_store_test.go b/pkg/core/storage/memcached_store_test.go index b3ac62cb3..cf7bcf40f 100644 --- a/pkg/core/storage/memcached_store_test.go +++ b/pkg/core/storage/memcached_store_test.go @@ -18,7 +18,7 @@ func TestMemCachedStorePersist(t *testing.T) { assert.Equal(t, 0, c) // persisting one key should result in one key in ps and nothing in ts assert.NoError(t, ts.Put([]byte("key"), []byte("value"))) - checkBatch(t, ts, []KeyValue{{[]byte("key"), []byte("value")}}, nil) + checkBatch(t, ts, []KeyValue{{Key: []byte("key"), Value: []byte("value")}}, nil) c, err = ts.Persist() checkBatch(t, ts, nil, nil) assert.Equal(t, nil, err) @@ -38,8 +38,8 @@ func TestMemCachedStorePersist(t *testing.T) { assert.Equal(t, ErrKeyNotFound, err) assert.Equal(t, []byte(nil), v) checkBatch(t, ts, []KeyValue{ - {[]byte("key"), []byte("newvalue")}, - {[]byte("key2"), []byte("value2")}, + {Key: []byte("key"), Value: []byte("newvalue"), Exists: true}, + {Key: []byte("key2"), Value: []byte("value2")}, }, nil) // two keys should be persisted (one overwritten and one new) and // available in the ps @@ -67,7 +67,7 @@ func TestMemCachedStorePersist(t *testing.T) { // test persisting deletions err = ts.Delete([]byte("key")) assert.Equal(t, nil, err) - checkBatch(t, ts, nil, []KeyValue{{Key: []byte("key")}}) + checkBatch(t, ts, nil, []KeyValue{{Key: []byte("key"), Exists: true}}) c, err = ts.Persist() checkBatch(t, ts, nil, nil) assert.Equal(t, nil, err)