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:
parent
79b930f6de
commit
c992d6c518
2 changed files with 30 additions and 8 deletions
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue