OSDN Git Service

Peer add announces new block message num limit
[bytom/vapor.git] / database / cache.go
index 7668d9c..a24ac8a 100644 (file)
@@ -1,7 +1,6 @@
 package database
 
 import (
-       "fmt"
        "strconv"
 
        "github.com/golang/groupcache/singleflight"
@@ -13,58 +12,64 @@ import (
 )
 
 const (
-       maxCachedBlockHeaders      = 1000
-       maxCachedBlockTransactions = 1000
-       maxCachedVoteResults       = 144 // int(60 * 60 * 24 * 1000 / consensus.BlockTimeInterval / consensus.RoundVoteBlockNums)
+       maxCachedBlockHeaders      = 4096
+       maxCachedBlockTransactions = 1024
+       maxCachedBlockHashes       = 8192
+       maxCachedMainChainHashes   = 8192
+       maxCachedConsensusResults  = 128
 )
 
-type fillBlockHeaderFn func(hash *bc.Hash, height uint64) (*types.BlockHeader, error)
+type fillBlockHeaderFn func(hash *bc.Hash) (*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, fillVoteResult fillVoteResultFn) blockCache {
-       return blockCache{
-               lruBlockHeaders: common.NewCache(maxCachedBlockHeaders),
-               lruBlockTxs:     common.NewCache(maxCachedBlockTransactions),
-               lruVoteResults:  common.NewCache(maxCachedVoteResults),
+type fillBlockHashesFn func(height uint64) ([]*bc.Hash, error)
+type fillMainChainHashFn func(height uint64) (*bc.Hash, error)
+type fillConsensusResultFn func(seq uint64) (*state.ConsensusResult, error)
+
+func newCache(fillBlockHeader fillBlockHeaderFn, fillBlockTxs fillBlockTransactionsFn, fillBlockHashes fillBlockHashesFn, fillMainChainHash fillMainChainHashFn, fillConsensusResult fillConsensusResultFn) cache {
+       return cache{
+               lruBlockHeaders:     common.NewCache(maxCachedBlockHeaders),
+               lruBlockTxs:         common.NewCache(maxCachedBlockTransactions),
+               lruBlockHashes:      common.NewCache(maxCachedBlockHashes),
+               lruMainChainHashes:  common.NewCache(maxCachedMainChainHashes),
+               lruConsensusResults: common.NewCache(maxCachedConsensusResults),
 
                fillBlockHeaderFn:      fillBlockHeader,
                fillBlockTransactionFn: fillBlockTxs,
-               fillVoteResultFn:       fillVoteResult,
+               fillBlockHashesFn:      fillBlockHashes,
+               fillMainChainHashFn:    fillMainChainHash,
+               fillConsensusResultFn:  fillConsensusResult,
        }
 }
 
-type blockCache struct {
-       lruBlockHeaders *common.Cache
-       lruBlockTxs     *common.Cache
-       lruVoteResults  *common.Cache
+type cache struct {
+       lruBlockHeaders     *common.Cache
+       lruBlockTxs         *common.Cache
+       lruBlockHashes      *common.Cache
+       lruMainChainHashes  *common.Cache
+       lruConsensusResults *common.Cache
 
-       fillBlockHeaderFn      func(hash *bc.Hash, height uint64) (*types.BlockHeader, error)
+       fillBlockHeaderFn      func(hash *bc.Hash) (*types.BlockHeader, error)
        fillBlockTransactionFn func(hash *bc.Hash) ([]*types.Tx, error)
-       fillVoteResultFn       func(seq uint64) (*state.VoteResult, error)
+       fillBlockHashesFn      func(uint64) ([]*bc.Hash, error)
+       fillMainChainHashFn    func(uint64) (*bc.Hash, error)
+       fillConsensusResultFn  func(seq uint64) (*state.ConsensusResult, error)
 
-       singleBlockHeader singleflight.Group
-       singleBlockTxs    singleflight.Group
-       singleVoteResult  singleflight.Group
+       sf singleflight.Group
 }
 
-func (c *blockCache) lookupBlockHeader(hash *bc.Hash, height uint64) (*types.BlockHeader, error) {
-       if bH, ok := c.getBlockHeader(hash); ok {
-               return bH, nil
+func (c *cache) lookupBlockHeader(hash *bc.Hash) (*types.BlockHeader, error) {
+       if data, ok := c.lruBlockHeaders.Get(*hash); ok {
+               return data.(*types.BlockHeader), nil
        }
 
-       blockHeader, err := c.singleBlockHeader.Do(hash.String(), func() (interface{}, error) {
-               bH, err := c.fillBlockHeaderFn(hash, height)
+       blockHeader, err := c.sf.Do("BlockHeader:"+hash.String(), func() (interface{}, error) {
+               blockHeader, err := c.fillBlockHeaderFn(hash)
                if err != nil {
                        return nil, err
                }
 
-               if bH == nil {
-                       return nil, fmt.Errorf("There are no blockHeader with given hash %s", hash.String())
-               }
-
-               c.addBlockHeader(bH)
-               return bH, nil
+               c.lruBlockHeaders.Add(blockHeader.Hash(), blockHeader)
+               return blockHeader, nil
        })
        if err != nil {
                return nil, err
@@ -72,87 +77,101 @@ 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) {
-       if bTxs, ok := c.getBlockTransactions(hash); ok {
-               return bTxs, nil
+func (c *cache) lookupBlockTxs(hash *bc.Hash) ([]*types.Tx, error) {
+       if data, ok := c.lruBlockTxs.Get(*hash); ok {
+               return data.([]*types.Tx), nil
        }
 
-       blockTransactions, err := c.singleBlockTxs.Do(hash.String(), func() (interface{}, error) {
-               bTxs, err := c.fillBlockTransactionFn(hash)
+       blockTxs, err := c.sf.Do("BlockTxs:"+hash.String(), func() (interface{}, error) {
+               blockTxs, err := c.fillBlockTransactionFn(hash)
                if err != nil {
                        return nil, err
                }
 
-               if bTxs == nil {
-                       return nil, fmt.Errorf("There are no block transactions with given hash %s", hash.String())
-               }
-
-               c.addBlockTxs(*hash, bTxs)
-               return bTxs, nil
+               c.lruBlockTxs.Add(*hash, blockTxs)
+               return blockTxs, nil
        })
        if err != nil {
                return nil, err
        }
-       return blockTransactions.([]*types.Tx), nil
+       return blockTxs.([]*types.Tx), nil
 }
 
-func (c *blockCache) lookupVoteResult(seq uint64) (*state.VoteResult, error) {
-       if vr, ok := c.getVoteResult(seq); ok {
-               return vr.Fork(), nil
+func (c *cache) lookupConsensusResult(seq uint64) (*state.ConsensusResult, error) {
+       if data, ok := c.lruConsensusResults.Get(seq); ok {
+               return data.(*state.ConsensusResult).Fork(), nil
        }
 
        seqStr := strconv.FormatUint(seq, 10)
-       voteResult, err := c.singleVoteResult.Do(seqStr, func() (interface{}, error) {
-               v, err := c.fillVoteResultFn(seq)
+       consensusResult, err := c.sf.Do("ConsensusResult:"+seqStr, func() (interface{}, error) {
+               consensusResult, err := c.fillConsensusResultFn(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.lruConsensusResults.Add(consensusResult.Seq, consensusResult)
+               return consensusResult, nil
+       })
+       if err != nil {
+               return nil, err
+       }
+       return consensusResult.(*state.ConsensusResult).Fork(), nil
+}
+
+func (c *cache) lookupMainChainHash(height uint64) (*bc.Hash, error) {
+       if hash, ok := c.lruMainChainHashes.Get(height); ok {
+               return hash.(*bc.Hash), nil
+       }
+
+       heightStr := strconv.FormatUint(height, 10)
+       hash, err := c.sf.Do("BlockHashByHeight:"+heightStr, func() (interface{}, error) {
+               hash, err := c.fillMainChainHashFn(height)
+               if err != nil {
+                       return nil, err
                }
 
-               c.addVoteResult(v)
-               return v, nil
+               c.lruMainChainHashes.Add(height, hash)
+               return hash, nil
        })
        if err != nil {
                return nil, err
        }
-       return voteResult.(*state.VoteResult).Fork(), nil
+       return hash.(*bc.Hash), nil
 }
 
-func (c *blockCache) getBlockHeader(hash *bc.Hash) (*types.BlockHeader, bool) {
-       blockHeader, ok := c.lruBlockHeaders.Get(*hash)
-       if blockHeader == nil {
-               return nil, ok
+func (c *cache) lookupBlockHashesByHeight(height uint64) ([]*bc.Hash, error) {
+       if hashes, ok := c.lruBlockHashes.Get(height); ok {
+               return hashes.([]*bc.Hash), nil
        }
-       return blockHeader.(*types.BlockHeader), ok
-}
 
-func (c *blockCache) getBlockTransactions(hash *bc.Hash) ([]*types.Tx, bool) {
-       txs, ok := c.lruBlockTxs.Get(*hash)
-       if txs == nil {
-               return nil, ok
+       heightStr := strconv.FormatUint(height, 10)
+       hashes, err := c.sf.Do("BlockHashesByHeight:"+heightStr, func() (interface{}, error) {
+               hashes, err := c.fillBlockHashesFn(height)
+               if err != nil {
+                       return nil, err
+               }
+
+               c.lruBlockHashes.Add(height, hashes)
+               return hashes, nil
+       })
+       if err != nil {
+               return nil, err
        }
-       return txs.([]*types.Tx), ok
+       return hashes.([]*bc.Hash), nil
 }
 
-func (c *blockCache) 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) removeBlockHeader(blockHeader *types.BlockHeader) {
+       c.lruBlockHeaders.Remove(blockHeader.Hash())
 }
 
-func (c *blockCache) addBlockHeader(blockHeader *types.BlockHeader) {
-       c.lruBlockHeaders.Add(blockHeader.Hash(), blockHeader)
+func (c *cache) removeBlockHashes(height uint64) {
+       c.lruBlockHashes.Remove(height)
 }
 
-func (c *blockCache) addBlockTxs(hash bc.Hash, txs []*types.Tx) {
-       c.lruBlockTxs.Add(hash, txs)
+func (c *cache) removeMainChainHash(height uint64) {
+       c.lruMainChainHashes.Remove(height)
 }
 
-func (c *blockCache) addVoteResult(voteResult *state.VoteResult) {
-       c.lruVoteResults.Add(voteResult.Seq, voteResult)
+func (c *cache) removeConsensusResult(consensusResult *state.ConsensusResult) {
+       c.lruConsensusResults.Remove(consensusResult.Seq)
 }