forked from TrueCloudLab/neoneo-go
e3af560d11
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.
58 lines
1 KiB
Go
58 lines
1 KiB
Go
package dao
|
|
|
|
import (
|
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
)
|
|
|
|
type (
|
|
itemState int
|
|
|
|
trackedItem struct {
|
|
state.StorageItem
|
|
State itemState
|
|
}
|
|
|
|
itemCache struct {
|
|
st map[util.Uint160]map[string]*trackedItem
|
|
keys map[util.Uint160][]string
|
|
}
|
|
)
|
|
|
|
const (
|
|
getOp itemState = 1 << iota
|
|
delOp
|
|
addOp
|
|
putOp
|
|
flushedState
|
|
)
|
|
|
|
func newItemCache() *itemCache {
|
|
return &itemCache{
|
|
make(map[util.Uint160]map[string]*trackedItem),
|
|
make(map[util.Uint160][]string),
|
|
}
|
|
}
|
|
|
|
func (c *itemCache) put(h util.Uint160, key []byte, op itemState, item *state.StorageItem) {
|
|
m := c.getItems(h)
|
|
m[string(key)] = &trackedItem{
|
|
StorageItem: *item,
|
|
State: op,
|
|
}
|
|
c.keys[h] = append(c.keys[h], string(key))
|
|
c.st[h] = m
|
|
}
|
|
|
|
func (c *itemCache) getItem(h util.Uint160, key []byte) *trackedItem {
|
|
m := c.getItems(h)
|
|
return m[string(key)]
|
|
}
|
|
|
|
func (c *itemCache) getItems(h util.Uint160) map[string]*trackedItem {
|
|
m, ok := c.st[h]
|
|
if !ok {
|
|
return make(map[string]*trackedItem)
|
|
}
|
|
return m
|
|
}
|