forked from TrueCloudLab/neoneo-go
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 (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"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/core/storage"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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
|
// Persist flushes all the changes made into the (supposedly) persistent
|
||||||
// underlying store.
|
// underlying store.
|
||||||
func (cd *cachedDao) Persist() (int, error) {
|
func (cd *cachedDao) Persist() (int, error) {
|
||||||
|
buf := io.NewBufBinWriter()
|
||||||
|
|
||||||
for sc := range cd.accounts {
|
for sc := range cd.accounts {
|
||||||
err := cd.dao.PutAccountState(cd.accounts[sc])
|
err := cd.dao.putAccountState(cd.accounts[sc], buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
buf.Reset()
|
||||||
}
|
}
|
||||||
for hash := range cd.unspents {
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
buf.Reset()
|
||||||
}
|
}
|
||||||
for acc, bs := range cd.balances {
|
for acc, bs := range cd.balances {
|
||||||
err := cd.dao.PutNEP5Balances(acc, bs)
|
err := cd.dao.putNEP5Balances(acc, bs, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
buf.Reset()
|
||||||
}
|
}
|
||||||
for acc, ts := range cd.transfers {
|
for acc, ts := range cd.transfers {
|
||||||
for ind, lg := range ts {
|
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.
|
// Put performs put operation with serializable structures.
|
||||||
func (dao *dao) Put(entity io.Serializable, key []byte) error {
|
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)
|
entity.EncodeBinary(buf.BinWriter)
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return buf.Err
|
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 {
|
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())
|
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.BytesBE())
|
||||||
return dao.Put(as, key)
|
return dao.putWithBuffer(as, key, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- end accounts.
|
// -- end accounts.
|
||||||
|
@ -148,10 +156,14 @@ func (dao *dao) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) {
|
||||||
return bs, nil
|
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 {
|
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())
|
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
|
||||||
return dao.Put(bs, key)
|
return dao.putWithBuffer(bs, key, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- end nep5 balances.
|
// -- 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.
|
// PutUnspentCoinState puts given UnspentCoinState into the given store.
|
||||||
func (dao *dao) PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error {
|
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())
|
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
|
||||||
return dao.Put(ucs, key)
|
return dao.putWithBuffer(ucs, key, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- end unspent coins.
|
// -- end unspent coins.
|
||||||
|
|
Loading…
Reference in a new issue