diff options
author | obscuren <geffobscura@gmail.com> | 2015-03-20 22:54:42 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-03-20 22:54:42 +0800 |
commit | deee9cb170ff105992ede83c52013d0c2c4ad10d (patch) | |
tree | a7e8a5267f0c3a03d26e20dc8bcd5f0b3a21feb9 /core/block_cache.go | |
parent | 01ff0b3176e6d83dcc5e6716f04301de71e3fc9e (diff) | |
download | dexon-deee9cb170ff105992ede83c52013d0c2c4ad10d.tar.gz dexon-deee9cb170ff105992ede83c52013d0c2c4ad10d.tar.zst dexon-deee9cb170ff105992ede83c52013d0c2c4ad10d.zip |
Added caching for block chain. Currently set to 10k
Diffstat (limited to 'core/block_cache.go')
-rw-r--r-- | core/block_cache.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/core/block_cache.go b/core/block_cache.go new file mode 100644 index 000000000..321021eb4 --- /dev/null +++ b/core/block_cache.go @@ -0,0 +1,68 @@ +package core + +import ( + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// BlockCache implements a caching mechanism specifically for blocks and uses FILO to pop +type BlockCache struct { + size int + + hashes []common.Hash + blocks map[common.Hash]*types.Block + + mu sync.RWMutex +} + +// Creates and returns a `BlockCache` with `size`. If `size` is smaller than 1 it will panic +func NewBlockCache(size int) *BlockCache { + if size < 1 { + panic("block cache size not allowed to be smaller than 1") + } + + bc := &BlockCache{size: size} + bc.Clear() + return bc +} + +func (bc *BlockCache) Clear() { + bc.blocks = make(map[common.Hash]*types.Block) + bc.hashes = nil + +} + +func (bc *BlockCache) Push(block *types.Block) { + bc.mu.Lock() + defer bc.mu.Unlock() + + if len(bc.hashes) == bc.size { + delete(bc.blocks, bc.hashes[0]) + + // XXX There are a few other options on solving this + // 1) use a poller / GC like mechanism to clean up untracked objects + // 2) copy as below + // re-use the slice and remove the reference to bc.hashes[0] + // this will allow the element to be garbage collected. + copy(bc.hashes, bc.hashes[1:]) + } else { + bc.hashes = append(bc.hashes, common.Hash{}) + } + + hash := block.Hash() + bc.blocks[hash] = block + bc.hashes[len(bc.hashes)-1] = hash +} + +func (bc *BlockCache) Get(hash common.Hash) *types.Block { + bc.mu.RLock() + defer bc.mu.RUnlock() + + if block, haz := bc.blocks[hash]; haz { + return block + } + + return nil +} |