github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/neatdb/memorydb/memorydb.go (about)

     1  package memorydb
     2  
     3  import (
     4  	"errors"
     5  	"sort"
     6  	"strings"
     7  	"sync"
     8  
     9  	"github.com/neatlab/neatio/neatdb"
    10  	"github.com/neatlab/neatio/utilities/common"
    11  )
    12  
    13  var (
    14  	errMemorydbClosed = errors.New("database closed")
    15  
    16  	errMemorydbNotFound = errors.New("not found")
    17  )
    18  
    19  type Database struct {
    20  	db   map[string][]byte
    21  	lock sync.RWMutex
    22  }
    23  
    24  func New() *Database {
    25  	return &Database{
    26  		db: make(map[string][]byte),
    27  	}
    28  }
    29  
    30  func NewWithCap(size int) *Database {
    31  	return &Database{
    32  		db: make(map[string][]byte, size),
    33  	}
    34  }
    35  
    36  func (db *Database) Close() error {
    37  	db.lock.Lock()
    38  	defer db.lock.Unlock()
    39  
    40  	db.db = nil
    41  	return nil
    42  }
    43  
    44  func (db *Database) Has(key []byte) (bool, error) {
    45  	db.lock.RLock()
    46  	defer db.lock.RUnlock()
    47  
    48  	if db.db == nil {
    49  		return false, errMemorydbClosed
    50  	}
    51  	_, ok := db.db[string(key)]
    52  	return ok, nil
    53  }
    54  
    55  func (db *Database) Get(key []byte) ([]byte, error) {
    56  	db.lock.RLock()
    57  	defer db.lock.RUnlock()
    58  
    59  	if db.db == nil {
    60  		return nil, errMemorydbClosed
    61  	}
    62  	if entry, ok := db.db[string(key)]; ok {
    63  		return common.CopyBytes(entry), nil
    64  	}
    65  	return nil, errMemorydbNotFound
    66  }
    67  
    68  func (db *Database) Put(key []byte, value []byte) error {
    69  	db.lock.Lock()
    70  	defer db.lock.Unlock()
    71  
    72  	if db.db == nil {
    73  		return errMemorydbClosed
    74  	}
    75  	db.db[string(key)] = common.CopyBytes(value)
    76  	return nil
    77  }
    78  
    79  func (db *Database) Delete(key []byte) error {
    80  	db.lock.Lock()
    81  	defer db.lock.Unlock()
    82  
    83  	if db.db == nil {
    84  		return errMemorydbClosed
    85  	}
    86  	delete(db.db, string(key))
    87  	return nil
    88  }
    89  
    90  func (db *Database) NewBatch() neatdb.Batch {
    91  	return &batch{
    92  		db: db,
    93  	}
    94  }
    95  
    96  func (db *Database) NewIterator() neatdb.Iterator {
    97  	return db.NewIteratorWithPrefix(nil)
    98  }
    99  
   100  func (db *Database) NewIteratorWithPrefix(prefix []byte) neatdb.Iterator {
   101  	db.lock.RLock()
   102  	defer db.lock.RUnlock()
   103  
   104  	var (
   105  		pr     = string(prefix)
   106  		keys   = make([]string, 0, len(db.db))
   107  		values = make([][]byte, 0, len(db.db))
   108  	)
   109  
   110  	for key := range db.db {
   111  		if strings.HasPrefix(key, pr) {
   112  			keys = append(keys, key)
   113  		}
   114  	}
   115  
   116  	sort.Strings(keys)
   117  	for _, key := range keys {
   118  		values = append(values, db.db[key])
   119  	}
   120  	return &iterator{
   121  		keys:   keys,
   122  		values: values,
   123  	}
   124  }
   125  
   126  func (db *Database) Stat(property string) (string, error) {
   127  	return "", errors.New("unknown property")
   128  }
   129  
   130  func (db *Database) Compact(start []byte, limit []byte) error {
   131  	return errors.New("unsupported operation")
   132  }
   133  
   134  func (db *Database) Len() int {
   135  	db.lock.RLock()
   136  	defer db.lock.RUnlock()
   137  
   138  	return len(db.db)
   139  }
   140  
   141  type keyvalue struct {
   142  	key    []byte
   143  	value  []byte
   144  	delete bool
   145  }
   146  
   147  type batch struct {
   148  	db     *Database
   149  	writes []keyvalue
   150  	size   int
   151  }
   152  
   153  func (b *batch) Put(key, value []byte) error {
   154  	b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false})
   155  	b.size += len(value)
   156  	return nil
   157  }
   158  
   159  func (b *batch) Delete(key []byte) error {
   160  	b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true})
   161  	b.size += 1
   162  	return nil
   163  }
   164  
   165  func (b *batch) ValueSize() int {
   166  	return b.size
   167  }
   168  
   169  func (b *batch) Write() error {
   170  	b.db.lock.Lock()
   171  	defer b.db.lock.Unlock()
   172  
   173  	for _, keyvalue := range b.writes {
   174  		if keyvalue.delete {
   175  			delete(b.db.db, string(keyvalue.key))
   176  			continue
   177  		}
   178  		b.db.db[string(keyvalue.key)] = keyvalue.value
   179  	}
   180  	return nil
   181  }
   182  
   183  func (b *batch) Reset() {
   184  	b.writes = b.writes[:0]
   185  	b.size = 0
   186  }
   187  
   188  func (b *batch) Replay(w neatdb.Writer) error {
   189  	for _, keyvalue := range b.writes {
   190  		if keyvalue.delete {
   191  			if err := w.Delete(keyvalue.key); err != nil {
   192  				return err
   193  			}
   194  			continue
   195  		}
   196  		if err := w.Put(keyvalue.key, keyvalue.value); err != nil {
   197  			return err
   198  		}
   199  	}
   200  	return nil
   201  }
   202  
   203  type iterator struct {
   204  	inited bool
   205  	keys   []string
   206  	values [][]byte
   207  }
   208  
   209  func (it *iterator) Next() bool {
   210  
   211  	if !it.inited {
   212  		it.inited = true
   213  		return len(it.keys) > 0
   214  	}
   215  
   216  	if len(it.keys) > 0 {
   217  		it.keys = it.keys[1:]
   218  		it.values = it.values[1:]
   219  	}
   220  	return len(it.keys) > 0
   221  }
   222  
   223  func (it *iterator) Error() error {
   224  	return nil
   225  }
   226  
   227  func (it *iterator) Key() []byte {
   228  	if len(it.keys) > 0 {
   229  		return []byte(it.keys[0])
   230  	}
   231  	return nil
   232  }
   233  
   234  func (it *iterator) Value() []byte {
   235  	if len(it.values) > 0 {
   236  		return it.values[0]
   237  	}
   238  	return nil
   239  }
   240  
   241  func (it *iterator) Release() {
   242  	it.keys, it.values = nil, nil
   243  }