mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-05 03:58:23 +00:00
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:
parent
69ccca675d
commit
e3af560d11
2 changed files with 8 additions and 4 deletions
|
@ -245,6 +245,7 @@ func (cd *Cached) FlushStorage() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ti.State |= flushedState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
func (cd *Cached) getStorageItemInt(scripthash util.Uint160, key []byte, putToCache bool) *state.StorageItem {
|
||||||
ti := cd.storage.getItem(scripthash, key)
|
ti := cd.storage.getItem(scripthash, key)
|
||||||
if ti != nil {
|
if ti != nil {
|
||||||
if ti.State == delOp {
|
if ti.State&delOp != 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return copyItem(&ti.StorageItem)
|
return copyItem(&ti.StorageItem)
|
||||||
|
@ -303,8 +304,10 @@ func (cd *Cached) PutStorageItem(scripthash util.Uint160, key []byte, si *state.
|
||||||
item := copyItem(si)
|
item := copyItem(si)
|
||||||
ti := cd.storage.getItem(scripthash, key)
|
ti := cd.storage.getItem(scripthash, key)
|
||||||
if ti != nil {
|
if ti != nil {
|
||||||
if ti.State == delOp || ti.State == getOp {
|
if ti.State&(delOp|getOp) != 0 {
|
||||||
ti.State = putOp
|
ti.State = putOp
|
||||||
|
} else {
|
||||||
|
ti.State = addOp
|
||||||
}
|
}
|
||||||
ti.StorageItem = *item
|
ti.StorageItem = *item
|
||||||
return nil
|
return nil
|
||||||
|
@ -357,7 +360,7 @@ func (cd *Cached) GetStorageItemsIterator(hash util.Uint160, prefix []byte) (Sto
|
||||||
for ; keyIndex < len(cd.storage.keys[hash]); keyIndex++ {
|
for ; keyIndex < len(cd.storage.keys[hash]); keyIndex++ {
|
||||||
k := cd.storage.keys[hash][keyIndex]
|
k := cd.storage.keys[hash][keyIndex]
|
||||||
v := cache[k]
|
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))
|
val := make([]byte, len(v.StorageItem.Value))
|
||||||
copy(val, v.StorageItem.Value)
|
copy(val, v.StorageItem.Value)
|
||||||
return []byte(k), val, nil
|
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] {
|
for _, k := range cd.storage.keys[hash] {
|
||||||
v := cache[k]
|
v := cache[k]
|
||||||
if v.State != delOp {
|
if v.State&delOp == 0 {
|
||||||
val := make([]byte, len(v.StorageItem.Value))
|
val := make([]byte, len(v.StorageItem.Value))
|
||||||
copy(val, v.StorageItem.Value)
|
copy(val, v.StorageItem.Value)
|
||||||
result = append(result, StorageItemWithKey{
|
result = append(result, StorageItemWithKey{
|
||||||
|
|
|
@ -24,6 +24,7 @@ const (
|
||||||
delOp
|
delOp
|
||||||
addOp
|
addOp
|
||||||
putOp
|
putOp
|
||||||
|
flushedState
|
||||||
)
|
)
|
||||||
|
|
||||||
func newItemCache() *itemCache {
|
func newItemCache() *itemCache {
|
||||||
|
|
Loading…
Reference in a new issue