From 8c902a72237b7969cd32ecec26386c9ab7be5f0c Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Mar 2020 12:13:02 +0300 Subject: [PATCH] core: cache UnspentCoins in cachedDao 1.5M block import time (VerifyBlocks disabled) on AMD Ryzen 5 1600/16GB/HDD, before: real 159m16.551s user 69m58.279s sys 7m34.334s after: real 139m41.836s user 67m12.477s sys 6m19.420s 12% which is even a bit more than could be expected from inputs analysis (that has around 10% cache hits for a block-wide cache), worth doing. --- pkg/core/cacheddao.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pkg/core/cacheddao.go b/pkg/core/cacheddao.go index 65e61c362..8e8d03e7d 100644 --- a/pkg/core/cacheddao.go +++ b/pkg/core/cacheddao.go @@ -13,13 +13,15 @@ type cachedDao struct { dao accounts map[util.Uint160]*state.Account contracts map[util.Uint160]*state.Contract + unspents map[util.Uint256]*state.UnspentCoin } // newCachedDao returns new cachedDao wrapping around given backing store. func newCachedDao(backend storage.Store) *cachedDao { accs := make(map[util.Uint160]*state.Account) ctrs := make(map[util.Uint160]*state.Contract) - return &cachedDao{*newDao(backend), accs, ctrs} + unspents := make(map[util.Uint256]*state.UnspentCoin) + return &cachedDao{*newDao(backend), accs, ctrs, unspents} } // GetAccountStateOrNew retrieves Account from cache or underlying Store @@ -69,6 +71,20 @@ func (cd *cachedDao) DeleteContractState(hash util.Uint160) error { return cd.dao.DeleteContractState(hash) } +// GetUnspentCoinState retrieves UnspentCoin from cache or underlying Store. +func (cd *cachedDao) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, error) { + if cd.unspents[hash] != nil { + return cd.unspents[hash], nil + } + return cd.dao.GetUnspentCoinState(hash) +} + +// PutUnspentCoinState saves given UnspentCoin in the cache. +func (cd *cachedDao) PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error { + cd.unspents[hash] = ucs + return nil +} + // Persist flushes all the changes made into the (supposedly) persistent // underlying store. func (cd *cachedDao) Persist() (int, error) { @@ -78,5 +94,11 @@ func (cd *cachedDao) Persist() (int, error) { return 0, err } } + for hash := range cd.unspents { + err := cd.dao.PutUnspentCoinState(hash, cd.unspents[hash]) + if err != nil { + return 0, err + } + } return cd.dao.Persist() }