core: reuse buffer in (*cacheddao).Persist()

When serializing multiple accounts, cost of a buffer grow
can become significant. This commit tries to amortize it by
reusing the same buffer in a single `Persist()` call.
This commit is contained in:
Evgenii Stratonikov 2020-03-17 12:06:46 +03:00
parent 79b930f6de
commit c992d6c518
2 changed files with 30 additions and 8 deletions

View file

@ -3,6 +3,7 @@ package core
import (
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
)
@ -138,23 +139,28 @@ func (cd *cachedDao) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *stat
// Persist flushes all the changes made into the (supposedly) persistent
// underlying store.
func (cd *cachedDao) Persist() (int, error) {
buf := io.NewBufBinWriter()
for sc := range cd.accounts {
err := cd.dao.PutAccountState(cd.accounts[sc])
err := cd.dao.putAccountState(cd.accounts[sc], buf)
if err != nil {
return 0, err
}
buf.Reset()
}
for hash := range cd.unspents {
err := cd.dao.PutUnspentCoinState(hash, cd.unspents[hash])
err := cd.dao.putUnspentCoinState(hash, cd.unspents[hash], buf)
if err != nil {
return 0, err
}
buf.Reset()
}
for acc, bs := range cd.balances {
err := cd.dao.PutNEP5Balances(acc, bs)
err := cd.dao.putNEP5Balances(acc, bs, buf)
if err != nil {
return 0, err
}
buf.Reset()
}
for acc, ts := range cd.transfers {
for ind, lg := range ts {

View file

@ -37,7 +37,11 @@ func (dao *dao) GetAndDecode(entity io.Serializable, key []byte) error {
// Put performs put operation with serializable structures.
func (dao *dao) Put(entity io.Serializable, key []byte) error {
buf := io.NewBufBinWriter()
return dao.putWithBuffer(entity, key, io.NewBufBinWriter())
}
// putWithBuffer performs put operation using buf as a pre-allocated buffer for serialization.
func (dao *dao) putWithBuffer(entity io.Serializable, key []byte, buf *io.BufBinWriter) error {
entity.EncodeBinary(buf.BinWriter)
if buf.Err != nil {
return buf.Err
@ -73,8 +77,12 @@ func (dao *dao) GetAccountState(hash util.Uint160) (*state.Account, error) {
}
func (dao *dao) PutAccountState(as *state.Account) error {
return dao.putAccountState(as, io.NewBufBinWriter())
}
func (dao *dao) putAccountState(as *state.Account, buf *io.BufBinWriter) error {
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.BytesBE())
return dao.Put(as, key)
return dao.putWithBuffer(as, key, buf)
}
// -- end accounts.
@ -148,10 +156,14 @@ func (dao *dao) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) {
return bs, nil
}
// GetNEP5Balances saves nep5 balances from the cache.
// PutNEP5Balances saves nep5 balances from the cache.
func (dao *dao) PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error {
return dao.putNEP5Balances(acc, bs, io.NewBufBinWriter())
}
func (dao *dao) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf *io.BufBinWriter) error {
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
return dao.Put(bs, key)
return dao.putWithBuffer(bs, key, buf)
}
// -- end nep5 balances.
@ -220,8 +232,12 @@ func (dao *dao) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, erro
// PutUnspentCoinState puts given UnspentCoinState into the given store.
func (dao *dao) PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error {
return dao.putUnspentCoinState(hash, ucs, io.NewBufBinWriter())
}
func (dao *dao) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin, buf *io.BufBinWriter) error {
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
return dao.Put(ucs, key)
return dao.putWithBuffer(ucs, key, buf)
}
// -- end unspent coins.