forked from TrueCloudLab/neoneo-go
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.
This commit is contained in:
parent
a1fecd2e88
commit
0a894db7f8
3 changed files with 19 additions and 8 deletions
|
@ -68,9 +68,14 @@ func batchToMap(index uint32, batch *storage.MemBatch) map[string]interface{} {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
op := "Added"
|
||||||
|
if batch.Put[i].Exists {
|
||||||
|
op = "Changed"
|
||||||
|
}
|
||||||
|
|
||||||
key = toNeoStorageKey(key[1:])
|
key = toNeoStorageKey(key[1:])
|
||||||
ops = append(ops, storageOp{
|
ops = append(ops, storageOp{
|
||||||
State: "Added",
|
State: op,
|
||||||
Key: hex.EncodeToString(key),
|
Key: hex.EncodeToString(key),
|
||||||
Value: "00" + hex.EncodeToString(batch.Put[i].Value),
|
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 {
|
for i := range batch.Deleted {
|
||||||
key := batch.Deleted[i].Key
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ type (
|
||||||
KeyValue struct {
|
KeyValue struct {
|
||||||
Key []byte
|
Key []byte
|
||||||
Value []byte
|
Value []byte
|
||||||
|
|
||||||
|
Exists bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemBatch represents a changeset to be persisted.
|
// MemBatch represents a changeset to be persisted.
|
||||||
|
@ -54,12 +56,16 @@ func (s *MemCachedStore) GetBatch() *MemBatch {
|
||||||
|
|
||||||
b.Put = make([]KeyValue, 0, len(s.mem))
|
b.Put = make([]KeyValue, 0, len(s.mem))
|
||||||
for k, v := range 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))
|
b.Deleted = make([]KeyValue, 0, len(s.del))
|
||||||
for k := range 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
|
return &b
|
||||||
|
|
|
@ -18,7 +18,7 @@ func TestMemCachedStorePersist(t *testing.T) {
|
||||||
assert.Equal(t, 0, c)
|
assert.Equal(t, 0, c)
|
||||||
// persisting one key should result in one key in ps and nothing in ts
|
// persisting one key should result in one key in ps and nothing in ts
|
||||||
assert.NoError(t, ts.Put([]byte("key"), []byte("value")))
|
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()
|
c, err = ts.Persist()
|
||||||
checkBatch(t, ts, nil, nil)
|
checkBatch(t, ts, nil, nil)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
@ -38,8 +38,8 @@ func TestMemCachedStorePersist(t *testing.T) {
|
||||||
assert.Equal(t, ErrKeyNotFound, err)
|
assert.Equal(t, ErrKeyNotFound, err)
|
||||||
assert.Equal(t, []byte(nil), v)
|
assert.Equal(t, []byte(nil), v)
|
||||||
checkBatch(t, ts, []KeyValue{
|
checkBatch(t, ts, []KeyValue{
|
||||||
{[]byte("key"), []byte("newvalue")},
|
{Key: []byte("key"), Value: []byte("newvalue"), Exists: true},
|
||||||
{[]byte("key2"), []byte("value2")},
|
{Key: []byte("key2"), Value: []byte("value2")},
|
||||||
}, nil)
|
}, nil)
|
||||||
// two keys should be persisted (one overwritten and one new) and
|
// two keys should be persisted (one overwritten and one new) and
|
||||||
// available in the ps
|
// available in the ps
|
||||||
|
@ -67,7 +67,7 @@ func TestMemCachedStorePersist(t *testing.T) {
|
||||||
// test persisting deletions
|
// test persisting deletions
|
||||||
err = ts.Delete([]byte("key"))
|
err = ts.Delete([]byte("key"))
|
||||||
assert.Equal(t, nil, err)
|
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()
|
c, err = ts.Persist()
|
||||||
checkBatch(t, ts, nil, nil)
|
checkBatch(t, ts, nil, nil)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
|
Loading…
Reference in a new issue