7 dbm "github.com/bytom/vapor/database/leveldb"
8 "github.com/bytom/vapor/errors"
9 "github.com/bytom/vapor/protocol/bc/types"
13 maxByteOfStorageRAM = 800 * 1024 * 1024 //100MB
14 errStorageFindBlock = errors.New("can't find block from storage")
15 errDBFindBlock = errors.New("can't find block from DB")
18 // LocalStore is the interface for persistent storage
19 type LocalStore interface {
20 writeBlock(block *types.Block) error
21 readBlock(height uint64) (*types.Block, error)
25 type blockStorage struct {
34 blocks map[uint64]*blockStorage
39 func newStorage(db dbm.DB) *storage {
40 DBStorage := newDBStore(db)
43 blocks: make(map[uint64]*blockStorage),
44 localStore: DBStorage,
48 func (s *storage) writeBlocks(peerID string, blocks []*types.Block) error {
52 for _, block := range blocks {
53 binaryBlock, err := block.MarshalText()
55 return errors.Wrap(err, "Marshal block header")
58 if len(binaryBlock)+s.actualUsage < maxByteOfStorageRAM {
59 s.blocks[block.Height] = &blockStorage{block: block, peerID: peerID, size: len(binaryBlock), isRAM: true}
60 s.actualUsage += len(binaryBlock)
64 if err := s.localStore.writeBlock(block); err != nil {
68 s.blocks[block.Height] = &blockStorage{peerID: peerID, isRAM: false}
74 func (s *storage) readBlock(height uint64) (*blockStorage, error) {
78 blockStore, ok := s.blocks[height]
80 return nil, errStorageFindBlock
84 return blockStore, nil
87 block, err := s.localStore.readBlock(height)
92 blockStore.block = block
93 return blockStore, nil
96 // deleteBlock delete blocks in memory
97 func (s *storage) deleteBlock(height uint64) {
101 blockStore, ok := s.blocks[height]
106 if blockStore.isRAM {
107 s.actualUsage -= blockStore.size
108 delete(s.blocks, height)
112 func (s *storage) resetParameter() {
116 s.blocks = make(map[uint64]*blockStorage)
118 s.localStore.clearData()
121 type levelDBStorage struct {
125 func newDBStore(db dbm.DB) *levelDBStorage {
126 return &levelDBStorage{
131 func (ls *levelDBStorage) clearData() {
132 iter := ls.db.Iterator()
136 ls.db.Delete(iter.Key())
140 func (ls *levelDBStorage) writeBlock(block *types.Block) error {
141 binaryBlock, err := block.MarshalText()
146 key := make([]byte, 8)
147 binary.BigEndian.PutUint64(key, block.Height)
148 ls.db.Set(key, binaryBlock)
152 func (ls *levelDBStorage) readBlock(height uint64) (*types.Block, error) {
153 key := make([]byte, 8)
154 binary.BigEndian.PutUint64(key, height)
155 binaryBlock := ls.db.Get(key)
156 if binaryBlock == nil {
157 return nil, errDBFindBlock
160 block := &types.Block{}
161 return block, block.UnmarshalText(binaryBlock)