OSDN Git Service

rename the block cache to cache
[bytom/vapor.git] / database / cache.go
index a525262..ca2803f 100644 (file)
@@ -2,44 +2,53 @@ package database
 
 import (
        "fmt"
+       "strconv"
 
        "github.com/golang/groupcache/singleflight"
 
        "github.com/vapor/common"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
+       "github.com/vapor/protocol/state"
 )
 
 const (
-       maxCachedBlockHeaders      = 1000
-       maxCachedBlockTransactions = 1000
+       maxCachedBlockHeaders      = 1024
+       maxCachedBlockTransactions = 1024
+       maxCachedVoteResults       = 144 // int(60 * 60 * 24 * 1000 / consensus.BlockTimeInterval / consensus.RoundVoteBlockNums)
 )
 
 type fillBlockHeaderFn func(hash *bc.Hash, height uint64) (*types.BlockHeader, error)
 type fillBlockTransactionsFn func(hash *bc.Hash) ([]*types.Tx, error)
+type fillVoteResultFn func(seq uint64) (*state.VoteResult, error)
 
-func newBlockCache(fillBlockHeader fillBlockHeaderFn, fillBlockTxs fillBlockTransactionsFn) blockCache {
-       return blockCache{
+func newCache(fillBlockHeader fillBlockHeaderFn, fillBlockTxs fillBlockTransactionsFn, fillVoteResult fillVoteResultFn) cache {
+       return cache{
                lruBlockHeaders: common.NewCache(maxCachedBlockHeaders),
                lruBlockTxs:     common.NewCache(maxCachedBlockTransactions),
+               lruVoteResults:  common.NewCache(maxCachedVoteResults),
 
                fillBlockHeaderFn:      fillBlockHeader,
                fillBlockTransactionFn: fillBlockTxs,
+               fillVoteResultFn:       fillVoteResult,
        }
 }
 
-type blockCache struct {
+type cache struct {
        lruBlockHeaders *common.Cache
        lruBlockTxs     *common.Cache
+       lruVoteResults  *common.Cache
 
        fillBlockHeaderFn      func(hash *bc.Hash, height uint64) (*types.BlockHeader, error)
        fillBlockTransactionFn func(hash *bc.Hash) ([]*types.Tx, error)
+       fillVoteResultFn       func(seq uint64) (*state.VoteResult, error)
 
        singleBlockHeader singleflight.Group
        singleBlockTxs    singleflight.Group
+       singleVoteResult  singleflight.Group
 }
 
-func (c *blockCache) lookupBlockHeader(hash *bc.Hash, height uint64) (*types.BlockHeader, error) {
+func (c *cache) lookupBlockHeader(hash *bc.Hash, height uint64) (*types.BlockHeader, error) {
        if bH, ok := c.getBlockHeader(hash); ok {
                return bH, nil
        }
@@ -63,7 +72,7 @@ func (c *blockCache) lookupBlockHeader(hash *bc.Hash, height uint64) (*types.Blo
        return blockHeader.(*types.BlockHeader), nil
 }
 
-func (c *blockCache) lookupBlockTxs(hash *bc.Hash) ([]*types.Tx, error) {
+func (c *cache) lookupBlockTxs(hash *bc.Hash) ([]*types.Tx, error) {
        if bTxs, ok := c.getBlockTransactions(hash); ok {
                return bTxs, nil
        }
@@ -87,7 +96,32 @@ func (c *blockCache) lookupBlockTxs(hash *bc.Hash) ([]*types.Tx, error) {
        return blockTransactions.([]*types.Tx), nil
 }
 
-func (c *blockCache) getBlockHeader(hash *bc.Hash) (*types.BlockHeader, bool) {
+func (c *cache) lookupVoteResult(seq uint64) (*state.VoteResult, error) {
+       if vr, ok := c.getVoteResult(seq); ok {
+               return vr.Fork(), nil
+       }
+
+       seqStr := strconv.FormatUint(seq, 10)
+       voteResult, err := c.singleVoteResult.Do(seqStr, func() (interface{}, error) {
+               v, err := c.fillVoteResultFn(seq)
+               if err != nil {
+                       return nil, err
+               }
+
+               if v == nil {
+                       return nil, fmt.Errorf("There are no vote result with given seq %s", seqStr)
+               }
+
+               c.addVoteResult(v)
+               return v, nil
+       })
+       if err != nil {
+               return nil, err
+       }
+       return voteResult.(*state.VoteResult).Fork(), nil
+}
+
+func (c *cache) getBlockHeader(hash *bc.Hash) (*types.BlockHeader, bool) {
        blockHeader, ok := c.lruBlockHeaders.Get(*hash)
        if blockHeader == nil {
                return nil, ok
@@ -95,7 +129,7 @@ func (c *blockCache) getBlockHeader(hash *bc.Hash) (*types.BlockHeader, bool) {
        return blockHeader.(*types.BlockHeader), ok
 }
 
-func (c *blockCache) getBlockTransactions(hash *bc.Hash) ([]*types.Tx, bool) {
+func (c *cache) getBlockTransactions(hash *bc.Hash) ([]*types.Tx, bool) {
        txs, ok := c.lruBlockTxs.Get(*hash)
        if txs == nil {
                return nil, ok
@@ -103,10 +137,22 @@ func (c *blockCache) getBlockTransactions(hash *bc.Hash) ([]*types.Tx, bool) {
        return txs.([]*types.Tx), ok
 }
 
-func (c *blockCache) addBlockHeader(blockHeader *types.BlockHeader) {
+func (c *cache) getVoteResult(seq uint64) (*state.VoteResult, bool) {
+       voteResult, ok := c.lruVoteResults.Get(seq)
+       if voteResult == nil {
+               return nil, ok
+       }
+       return voteResult.(*state.VoteResult), ok
+}
+
+func (c *cache) addBlockHeader(blockHeader *types.BlockHeader) {
        c.lruBlockHeaders.Add(blockHeader.Hash(), blockHeader)
 }
 
-func (c *blockCache) addBlockTxs(hash bc.Hash, txs []*types.Tx) {
+func (c *cache) addBlockTxs(hash bc.Hash, txs []*types.Tx) {
        c.lruBlockTxs.Add(hash, txs)
 }
+
+func (c *cache) addVoteResult(voteResult *state.VoteResult) {
+       c.lruVoteResults.Add(voteResult.Seq, voteResult)
+}