dao: optimize storage cache flushing

Items were serialized several times if there were several successful
transactions in a block, prevent that by using State field as a bitfield (as
it almost was intended to) and adding one more bit. It also eliminates useless
duplicate MPT traversions.

Confirmed to not break storage changes up to 3.3M on testnet.
This commit is contained in:
Roman Khimov 2020-06-04 17:21:58 +03:00
parent 69ccca675d
commit e3af560d11
2 changed files with 8 additions and 4 deletions

View file

@ -245,6 +245,7 @@ func (cd *Cached) FlushStorage() error {
return err
}
}
ti.State |= flushedState
}
}
return nil
@ -275,7 +276,7 @@ func (cd *Cached) getStorageItemNoCache(scripthash util.Uint160, key []byte) *st
func (cd *Cached) getStorageItemInt(scripthash util.Uint160, key []byte, putToCache bool) *state.StorageItem {
ti := cd.storage.getItem(scripthash, key)
if ti != nil {
if ti.State == delOp {
if ti.State&delOp != 0 {
return nil
}
return copyItem(&ti.StorageItem)
@ -303,8 +304,10 @@ func (cd *Cached) PutStorageItem(scripthash util.Uint160, key []byte, si *state.
item := copyItem(si)
ti := cd.storage.getItem(scripthash, key)
if ti != nil {
if ti.State == delOp || ti.State == getOp {
if ti.State&(delOp|getOp) != 0 {
ti.State = putOp
} else {
ti.State = addOp
}
ti.StorageItem = *item
return nil
@ -357,7 +360,7 @@ func (cd *Cached) GetStorageItemsIterator(hash util.Uint160, prefix []byte) (Sto
for ; keyIndex < len(cd.storage.keys[hash]); keyIndex++ {
k := cd.storage.keys[hash][keyIndex]
v := cache[k]
if v.State != delOp && bytes.HasPrefix([]byte(k), prefix) {
if v.State&delOp == 0 && bytes.HasPrefix([]byte(k), prefix) {
val := make([]byte, len(v.StorageItem.Value))
copy(val, v.StorageItem.Value)
return []byte(k), val, nil
@ -404,7 +407,7 @@ func (cd *Cached) GetStorageItems(hash util.Uint160, prefix []byte) ([]StorageIt
for _, k := range cd.storage.keys[hash] {
v := cache[k]
if v.State != delOp {
if v.State&delOp == 0 {
val := make([]byte, len(v.StorageItem.Value))
copy(val, v.StorageItem.Value)
result = append(result, StorageItemWithKey{

View file

@ -24,6 +24,7 @@ const (
delOp
addOp
putOp
flushedState
)
func newItemCache() *itemCache {