github.com/klaytn/klaytn@v1.12.1/storage/database/memory_database.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from ethdb/memory_database.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package database
    22  
    23  import (
    24  	"errors"
    25  	"sort"
    26  	"strings"
    27  	"sync"
    28  
    29  	"github.com/klaytn/klaytn/common"
    30  )
    31  
    32  // errMemorydbClosed is returned if a memory database was already closed at the
    33  // invocation of a data access operation.
    34  var errMemorydbClosed = errors.New("database closed")
    35  
    36  /*
    37   * This is a test memory database. Do not use for any production it does not get persisted
    38   */
    39  type MemDB struct {
    40  	db   map[string][]byte
    41  	lock sync.RWMutex
    42  }
    43  
    44  func NewMemDB() *MemDB {
    45  	return &MemDB{
    46  		db: make(map[string][]byte),
    47  	}
    48  }
    49  
    50  func NewMemDBWithCap(size int) *MemDB {
    51  	return &MemDB{
    52  		db: make(map[string][]byte, size),
    53  	}
    54  }
    55  
    56  // Close deallocates the internal map and ensures any consecutive data access op
    57  // fails with an error.
    58  func (db *MemDB) Close() {
    59  	db.lock.Lock()
    60  	defer db.lock.Unlock()
    61  
    62  	db.db = nil
    63  }
    64  
    65  func (db *MemDB) Type() DBType {
    66  	return MemoryDB
    67  }
    68  
    69  // Has retrieves if a key is present in the key-value store.
    70  func (db *MemDB) Has(key []byte) (bool, error) {
    71  	db.lock.RLock()
    72  	defer db.lock.RUnlock()
    73  
    74  	if db.db == nil {
    75  		return false, errMemorydbClosed
    76  	}
    77  	_, ok := db.db[string(key)]
    78  	return ok, nil
    79  }
    80  
    81  // Get retrieves the given key if it's present in the key-value store.
    82  func (db *MemDB) Get(key []byte) ([]byte, error) {
    83  	db.lock.RLock()
    84  	defer db.lock.RUnlock()
    85  
    86  	if db.db == nil {
    87  		return nil, errMemorydbClosed
    88  	}
    89  	if entry, ok := db.db[string(key)]; ok {
    90  		if entry == nil {
    91  			entry = []byte{}
    92  		}
    93  		return common.CopyBytes(entry), nil
    94  	}
    95  	return nil, dataNotFoundErr
    96  }
    97  
    98  // Put inserts the given value into the key-value store.
    99  func (db *MemDB) Put(key []byte, value []byte) error {
   100  	db.lock.Lock()
   101  	defer db.lock.Unlock()
   102  
   103  	if db.db == nil {
   104  		return errMemorydbClosed
   105  	}
   106  	db.db[string(key)] = common.CopyBytes(value)
   107  	return nil
   108  }
   109  
   110  // Delete removes the key from the key-value store.
   111  func (db *MemDB) Delete(key []byte) error {
   112  	db.lock.Lock()
   113  	defer db.lock.Unlock()
   114  
   115  	if db.db == nil {
   116  		return errMemorydbClosed
   117  	}
   118  	delete(db.db, string(key))
   119  	return nil
   120  }
   121  
   122  func (db *MemDB) Keys() [][]byte {
   123  	db.lock.RLock()
   124  	defer db.lock.RUnlock()
   125  
   126  	keys := [][]byte{}
   127  	for key := range db.db {
   128  		keys = append(keys, []byte(key))
   129  	}
   130  	return keys
   131  }
   132  
   133  func (db *MemDB) NewBatch() Batch {
   134  	return &memBatch{db: db}
   135  }
   136  
   137  // NewIterator creates a binary-alphabetical iterator over a subset
   138  // of database content with a particular key prefix, starting at a particular
   139  // initial key (or after, if it does not exist).
   140  func (db *MemDB) NewIterator(prefix []byte, start []byte) Iterator {
   141  	db.lock.RLock()
   142  	defer db.lock.RUnlock()
   143  
   144  	var (
   145  		pr     = string(prefix)
   146  		st     = string(append(prefix, start...))
   147  		keys   = make([]string, 0, len(db.db))
   148  		values = make([][]byte, 0, len(db.db))
   149  	)
   150  	// Collect the keys from the memory database corresponding to the given prefix
   151  	// and start
   152  	for key := range db.db {
   153  		if !strings.HasPrefix(key, pr) {
   154  			continue
   155  		}
   156  		if key >= st {
   157  			keys = append(keys, key)
   158  		}
   159  	}
   160  	// Sort the items and retrieve the associated values
   161  	sort.Strings(keys)
   162  	for _, key := range keys {
   163  		values = append(values, db.db[key])
   164  	}
   165  	return &iterator{
   166  		keys:   keys,
   167  		values: values,
   168  	}
   169  }
   170  
   171  // Stat returns a particular internal stat of the database.
   172  func (db *MemDB) Stat(property string) (string, error) {
   173  	return "", errors.New("unknown property")
   174  }
   175  
   176  // Compact is not supported on a memory database, but there's no need either as
   177  // a memory database doesn't waste space anyway.
   178  func (db *MemDB) Compact(start []byte, limit []byte) error {
   179  	return nil
   180  }
   181  
   182  // Len returns the number of entries currently present in the memory database.
   183  //
   184  // Note, this method is only used for testing (i.e. not public in general) and
   185  // does not have explicit checks for closed-ness to allow simpler testing code.
   186  func (db *MemDB) Len() int {
   187  	db.lock.RLock()
   188  	defer db.lock.RUnlock()
   189  
   190  	return len(db.db)
   191  }
   192  
   193  func (db *MemDB) Meter(prefix string) {
   194  	logger.Warn("MemDB does not support metrics!")
   195  }
   196  
   197  func (db *MemDB) TryCatchUpWithPrimary() error {
   198  	return nil
   199  }
   200  
   201  // keyvalue is a key-value tuple tagged with a deletion field to allow creating
   202  // memory-database write batches.
   203  type keyvalue struct {
   204  	key    []byte
   205  	value  []byte
   206  	delete bool
   207  }
   208  
   209  // memBatch is a write-only memory batch that commits changes to its host
   210  // database when Write is called. A batch cannot be used concurrently.
   211  type memBatch struct {
   212  	db     *MemDB
   213  	writes []keyvalue
   214  	size   int
   215  }
   216  
   217  // Put inserts the given value into the batch for later committing.
   218  func (b *memBatch) Put(key, value []byte) error {
   219  	b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false})
   220  	b.size += len(value)
   221  	return nil
   222  }
   223  
   224  // Delete inserts the a key removal into the batch for later committing.
   225  func (b *memBatch) Delete(key []byte) error {
   226  	b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true})
   227  	b.size += 1
   228  	return nil
   229  }
   230  
   231  // ValueSize retrieves the amount of data queued up for writing.
   232  func (b *memBatch) ValueSize() int {
   233  	return b.size
   234  }
   235  
   236  // Write flushes any accumulated data to the memory database.
   237  func (b *memBatch) Write() error {
   238  	b.db.lock.Lock()
   239  	defer b.db.lock.Unlock()
   240  
   241  	for _, keyvalue := range b.writes {
   242  		if keyvalue.delete {
   243  			delete(b.db.db, string(keyvalue.key))
   244  			continue
   245  		}
   246  		b.db.db[string(keyvalue.key)] = keyvalue.value
   247  	}
   248  	return nil
   249  }
   250  
   251  // Reset resets the batch for reuse.
   252  func (b *memBatch) Reset() {
   253  	b.writes = b.writes[:0]
   254  	b.size = 0
   255  }
   256  
   257  func (b *memBatch) Release() {
   258  	// nothing to do with memBatch
   259  }
   260  
   261  // Replay replays the batch contents.
   262  func (b *memBatch) Replay(w KeyValueWriter) error {
   263  	for _, keyvalue := range b.writes {
   264  		if keyvalue.delete {
   265  			if err := w.Delete(keyvalue.key); err != nil {
   266  				return err
   267  			}
   268  			continue
   269  		}
   270  		if err := w.Put(keyvalue.key, keyvalue.value); err != nil {
   271  			return err
   272  		}
   273  	}
   274  	return nil
   275  }
   276  
   277  // iterator can walk over the (potentially partial) keyspace of a memory key
   278  // value store. Internally it is a deep copy of the entire iterated state,
   279  // sorted by keys.
   280  type iterator struct {
   281  	inited bool
   282  	keys   []string
   283  	values [][]byte
   284  }
   285  
   286  // Next moves the iterator to the next key/value pair. It returns whether the
   287  // iterator is exhausted.
   288  func (it *iterator) Next() bool {
   289  	// If the iterator was not yet initialized, do it now
   290  	if !it.inited {
   291  		it.inited = true
   292  		return len(it.keys) > 0
   293  	}
   294  	// Iterator already initialize, advance it
   295  	if len(it.keys) > 0 {
   296  		it.keys = it.keys[1:]
   297  		it.values = it.values[1:]
   298  	}
   299  	return len(it.keys) > 0
   300  }
   301  
   302  // Error returns any accumulated error. Exhausting all the key/value pairs
   303  // is not considered to be an error. A memory iterator cannot encounter errors.
   304  func (it *iterator) Error() error {
   305  	return nil
   306  }
   307  
   308  // Key returns the key of the current key/value pair, or nil if done. The caller
   309  // should not modify the contents of the returned slice, and its contents may
   310  // change on the next call to Next.
   311  func (it *iterator) Key() []byte {
   312  	if !it.inited {
   313  		return nil
   314  	}
   315  	if len(it.keys) > 0 {
   316  		return []byte(it.keys[0])
   317  	}
   318  	return nil
   319  }
   320  
   321  // Value returns the value of the current key/value pair, or nil if done. The
   322  // caller should not modify the contents of the returned slice, and its contents
   323  // may change on the next call to Next.
   324  func (it *iterator) Value() []byte {
   325  	if !it.inited {
   326  		return nil
   327  	}
   328  	if len(it.values) > 0 {
   329  		return it.values[0]
   330  	}
   331  	return nil
   332  }
   333  
   334  // Release releases associated resources. Release should always succeed and can
   335  // be called multiple times without causing error.
   336  func (it *iterator) Release() {
   337  	it.keys, it.values = nil, nil
   338  }