github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/ethdb/memory_database.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:38</date>
    10  //</624450090529984512>
    11  
    12  
    13  package ethdb
    14  
    15  import (
    16  	"errors"
    17  	"sync"
    18  
    19  	"github.com/ethereum/go-ethereum/common"
    20  )
    21  
    22  /*
    23   *这是一个测试内存数据库。不要用于任何不持久化的产品
    24   **/
    25  
    26  type MemDatabase struct {
    27  	db   map[string][]byte
    28  	lock sync.RWMutex
    29  }
    30  
    31  func NewMemDatabase() *MemDatabase {
    32  	return &MemDatabase{
    33  		db: make(map[string][]byte),
    34  	}
    35  }
    36  
    37  func NewMemDatabaseWithCap(size int) *MemDatabase {
    38  	return &MemDatabase{
    39  		db: make(map[string][]byte, size),
    40  	}
    41  }
    42  
    43  func (db *MemDatabase) Put(key []byte, value []byte) error {
    44  	db.lock.Lock()
    45  	defer db.lock.Unlock()
    46  
    47  	db.db[string(key)] = common.CopyBytes(value)
    48  	return nil
    49  }
    50  
    51  func (db *MemDatabase) Has(key []byte) (bool, error) {
    52  	db.lock.RLock()
    53  	defer db.lock.RUnlock()
    54  
    55  	_, ok := db.db[string(key)]
    56  	return ok, nil
    57  }
    58  
    59  func (db *MemDatabase) Get(key []byte) ([]byte, error) {
    60  	db.lock.RLock()
    61  	defer db.lock.RUnlock()
    62  
    63  	if entry, ok := db.db[string(key)]; ok {
    64  		return common.CopyBytes(entry), nil
    65  	}
    66  	return nil, errors.New("not found")
    67  }
    68  
    69  func (db *MemDatabase) Keys() [][]byte {
    70  	db.lock.RLock()
    71  	defer db.lock.RUnlock()
    72  
    73  	keys := [][]byte{}
    74  	for key := range db.db {
    75  		keys = append(keys, []byte(key))
    76  	}
    77  	return keys
    78  }
    79  
    80  func (db *MemDatabase) Delete(key []byte) error {
    81  	db.lock.Lock()
    82  	defer db.lock.Unlock()
    83  
    84  	delete(db.db, string(key))
    85  	return nil
    86  }
    87  
    88  func (db *MemDatabase) Close() {}
    89  
    90  func (db *MemDatabase) NewBatch() Batch {
    91  	return &memBatch{db: db}
    92  }
    93  
    94  func (db *MemDatabase) Len() int { return len(db.db) }
    95  
    96  type kv struct {
    97  	k, v []byte
    98  	del  bool
    99  }
   100  
   101  type memBatch struct {
   102  	db     *MemDatabase
   103  	writes []kv
   104  	size   int
   105  }
   106  
   107  func (b *memBatch) Put(key, value []byte) error {
   108  	b.writes = append(b.writes, kv{common.CopyBytes(key), common.CopyBytes(value), false})
   109  	b.size += len(value)
   110  	return nil
   111  }
   112  
   113  func (b *memBatch) Delete(key []byte) error {
   114  	b.writes = append(b.writes, kv{common.CopyBytes(key), nil, true})
   115  	b.size += 1
   116  	return nil
   117  }
   118  
   119  func (b *memBatch) Write() error {
   120  	b.db.lock.Lock()
   121  	defer b.db.lock.Unlock()
   122  
   123  	for _, kv := range b.writes {
   124  		if kv.del {
   125  			delete(b.db.db, string(kv.k))
   126  			continue
   127  		}
   128  		b.db.db[string(kv.k)] = kv.v
   129  	}
   130  	return nil
   131  }
   132  
   133  func (b *memBatch) ValueSize() int {
   134  	return b.size
   135  }
   136  
   137  func (b *memBatch) Reset() {
   138  	b.writes = b.writes[:0]
   139  	b.size = 0
   140  }
   141