7 dbm "github.com/vapor/database/leveldb"
8 "github.com/vapor/errors"
9 "github.com/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 type Storage interface {
20 writeBlocks(peerID string, blocks []*types.Block) error
21 readBlock(height uint64) (*blockStorage, error)
22 deleteBlock(height uint64)
25 type LocalStore interface {
26 writeBlock(block *types.Block) error
27 readBlock(height uint64) (*types.Block, error)
31 type blockStorage struct {
40 blocks map[uint64]*blockStorage
45 func newStorage(db dbm.DB) *storage {
46 DBStorage := newDBStore(db)
49 blocks: make(map[uint64]*blockStorage),
50 localStore: DBStorage,
54 func (s *storage) writeBlocks(peerID string, blocks []*types.Block) error {
58 for _, block := range blocks {
59 binaryBlock, err := block.MarshalText()
61 return errors.Wrap(err, "Marshal block header")
64 if len(binaryBlock)+s.actualUsage < maxByteOfStorageRAM {
65 s.blocks[block.Height] = &blockStorage{block: block, peerID: peerID, size: len(binaryBlock), isRAM: true}
66 s.actualUsage += len(binaryBlock)
70 if err := s.localStore.writeBlock(block); err != nil {
74 s.blocks[block.Height] = &blockStorage{peerID: peerID, isRAM: false}
80 func (s *storage) readBlock(height uint64) (*blockStorage, error) {
84 blockStore, ok := s.blocks[height]
86 return nil, errStorageFindBlock
90 return blockStore, nil
93 block, err := s.localStore.readBlock(height)
98 blockStore.block = block
99 return blockStore, nil
102 // deleteBlock delete blocks in memory
103 func (s *storage) deleteBlock(height uint64) {
105 defer s.mux.RUnlock()
107 blockStore, ok := s.blocks[height]
112 if blockStore.isRAM {
113 s.actualUsage -= blockStore.size
114 delete(s.blocks, height)
118 func (s *storage) resetParameter() {
122 s.blocks = make(map[uint64]*blockStorage)
124 s.localStore.clearData()
127 type levelDBStorage struct {
131 func newDBStore(db dbm.DB) *levelDBStorage {
132 return &levelDBStorage{
137 func (ls *levelDBStorage) clearData() {
138 iter := ls.db.Iterator()
142 ls.db.Delete(iter.Key())
146 func (ls *levelDBStorage) writeBlock(block *types.Block) error {
147 binaryBlock, err := block.MarshalText()
152 key := make([]byte, 8)
153 binary.BigEndian.PutUint64(key, block.Height)
154 ls.db.Set(key, binaryBlock)
158 func (ls *levelDBStorage) readBlock(height uint64) (*types.Block, error) {
159 key := make([]byte, 8)
160 binary.BigEndian.PutUint64(key, height)
161 binaryBlock := ls.db.Get(key)
162 if binaryBlock == nil {
163 return nil, errDBFindBlock
166 block := &types.Block{}
167 return block, block.UnmarshalText(binaryBlock)