stasatdaglabs 0fa13357c3
[NOD-1566] Add caching to all stores (#1152)
* [NOD-1566] Add a dependency to golang-lru.

* [NOD-1566] Add caching to blockstore.go.

* [NOD-1566] Add LRUCache to all store objects and initialize them.

* [NOD-1566] Add caching to acceptanceDataStore.

* [NOD-1566] Add caching to blockHeaderStore.

* [NOD-1566] Implement a simpler LRU cache.

* [NOD-1566] Use the simpler cache implementation everywhere.

* [NOD-1566] Remove dependency in golang-lru.

* [NOD-1566] Fix object reuse issues in store Get functions.

* [NOD-1566] Add caching to blockRelationStore.

* [NOD-1566] Add caching to blockStatusStore.

* [NOD-1566] Add caching to ghostdagDataStore.

* [NOD-1566] Add caching to multisetStore.

* [NOD-1566] Add caching to reachabilityDataStore.

* [NOD-1566] Add caching to utxoDiffStore.

* [NOD-1566] Add caching to reachabilityReindexRoot.

* [NOD-1566] Add caching to pruningStore.

* [NOD-1566] Add caching to headerTipsStore.

* [NOD-1566] Add caching to consensusStateStore.

* [NOD-1566] Add comments explaining why we don't discard staging at the normal location in consensusStateStore.

* [NOD-1566] Make go vet happy.

* [NOD-1566] Fix merge errors.

* [NOD-1566] Add a missing break statement.

* [NOD-1566] Run go mod tidy.

* [NOD-1566] Remove serializedUTXOSetCache.
2020-11-25 13:41:13 +02:00

102 lines
2.3 KiB
Go

package headertipsstore
import (
"github.com/golang/protobuf/proto"
"github.com/kaspanet/kaspad/domain/consensus/database/serialization"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/dbkeys"
)
var headerTipsKey = dbkeys.MakeBucket().Key([]byte("header-tips"))
type headerTipsStore struct {
staging []*externalapi.DomainHash
cache []*externalapi.DomainHash
}
// New instantiates a new HeaderTipsStore
func New() model.HeaderTipsStore {
return &headerTipsStore{}
}
func (hts *headerTipsStore) HasTips(dbContext model.DBReader) (bool, error) {
if len(hts.staging) > 0 {
return true, nil
}
if len(hts.cache) > 0 {
return true, nil
}
return dbContext.Has(headerTipsKey)
}
func (hts *headerTipsStore) Discard() {
hts.staging = nil
}
func (hts *headerTipsStore) Commit(dbTx model.DBTransaction) error {
if hts.staging == nil {
return nil
}
tipsBytes, err := hts.serializeTips(hts.staging)
if err != nil {
return err
}
err = dbTx.Put(headerTipsKey, tipsBytes)
if err != nil {
return err
}
hts.cache = hts.staging
hts.Discard()
return nil
}
func (hts *headerTipsStore) Stage(tips []*externalapi.DomainHash) {
hts.staging = externalapi.CloneHashes(tips)
}
func (hts *headerTipsStore) IsStaged() bool {
return hts.staging != nil
}
func (hts *headerTipsStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
if hts.staging != nil {
return externalapi.CloneHashes(hts.staging), nil
}
if hts.cache != nil {
return externalapi.CloneHashes(hts.cache), nil
}
tipsBytes, err := dbContext.Get(headerTipsKey)
if err != nil {
return nil, err
}
tips, err := hts.deserializeTips(tipsBytes)
if err != nil {
return nil, err
}
hts.cache = tips
return externalapi.CloneHashes(tips), nil
}
func (hts *headerTipsStore) serializeTips(tips []*externalapi.DomainHash) ([]byte, error) {
dbTips := serialization.HeaderTipsToDBHeaderTips(tips)
return proto.Marshal(dbTips)
}
func (hts *headerTipsStore) deserializeTips(tipsBytes []byte) ([]*externalapi.DomainHash, error) {
dbTips := &serialization.DbHeaderTips{}
err := proto.Unmarshal(tipsBytes, dbTips)
if err != nil {
return nil, err
}
return serialization.DBHeaderTipsToHeaderTips(dbTips)
}