高效的内存区块缓存容器

下面的缓存实现主要应用于存储最新区块, 假定产生的块是连续的,我们需要把块存起来,从而提高取数据的效率,缓存的容器大小为100,大小可以调整,当缓存满了, 后面的块需要替换最早的区块,从而达到容器存的最新的块。下面是技术实现:

package main

import (
	"container/list"
	"errors"
	"fmt"
)

const BlockMaxVolume = 5 //区块的内存容量

type BlockInfo struct {
	BlockNumber string
	Data interface{}
}

type MemoryBlockDatas struct {
	blocks *list.List
}

func (datas *MemoryBlockDatas) AddBlock(block BlockInfo) (string, error) {
	if BlockMaxVolume <= 0  {
		return "", errors.New("内存容量不能为零以下")
	}
	if datas.blocks == nil {
		datas.blocks = list.New()
	}
	if datas.blocks.Len() < BlockMaxVolume {
		datas.blocks.PushBack(block)
	} else {
		headElem := datas.blocks.Front()
		datas.blocks.Remove(headElem)
		datas.blocks.PushBack(block)
	}
	return block.BlockNumber, nil
}

//获取最新的区块数
func (datas *MemoryBlockDatas) GetLatestBlocks(blockNumber int) ([]BlockInfo, error) {
	if blockNumber <=0 {
		return nil, errors.New("区块数不能为零")
	}
	if blockNumber > BlockMaxVolume {
		blockNumber = BlockMaxVolume
	}
	var blocks []BlockInfo
	for elem := datas.blocks.Back(); elem != nil; elem =  elem.Prev() {
		if blockNumber <= 0 {
			break
		}
		blocks = append(blocks, elem.Value.(BlockInfo))
		blockNumber--
	}

	return blocks, nil
}

func (datas MemoryBlockDatas) GetBlockNumber() int {
	return datas.blocks.Len()
}

func (datas MemoryBlockDatas) PrintBlocks() {
	for elem := datas.blocks.Front(); elem != nil; elem =  elem.Next() {
		fmt.Printf("key=%s, value=%v\n", elem.Value.(BlockInfo).BlockNumber, elem.Value.(BlockInfo).Data)
	}
}

func main() {
		fmt.Printf("打印区块\n")
		var datas MemoryBlockDatas
		datas.AddBlock(BlockInfo{"one", "hello"})
		datas.AddBlock(BlockInfo{"two", "how"})
		datas.AddBlock(BlockInfo{"three", "are"})
		datas.AddBlock(BlockInfo{"four", "you"})
		datas.AddBlock(BlockInfo{"five", "I"})
		datas.AddBlock(BlockInfo{"six", "love"})
	        datas.AddBlock(BlockInfo{"seven", "you"})
		datas.PrintBlocks()

		//打印最新区块
		blocks, err := datas.GetLatestBlocks(4)
		if err != nil {
			fmt.Println(err)
		}
		fmt.Println("打印最新区块")
		for _, elem := range blocks {
			fmt.Printf("key=%s, value=%v\n", elem.BlockNumber, elem.Data)
		}

		fmt.Println("内存区块数量:",datas.GetBlockNumber())

}

猜你喜欢

转载自blog.csdn.net/jujueduoluo/article/details/80084926