github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/leveldb/go_level_db.go (about)

     1  package leveldb
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  
     7  	"github.com/syndtr/goleveldb/leveldb"
     8  	"github.com/syndtr/goleveldb/leveldb/errors"
     9  	"github.com/syndtr/goleveldb/leveldb/iterator"
    10  	"github.com/syndtr/goleveldb/leveldb/opt"
    11  	"github.com/syndtr/goleveldb/leveldb/util"
    12  
    13  	. "github.com/tendermint/tmlibs/common"
    14  )
    15  
    16  func init() {
    17  	dbCreator := func(name string, dir string) (DB, error) {
    18  		return NewGoLevelDB(name, dir)
    19  	}
    20  	registerDBCreator(LevelDBBackendStr, dbCreator, false)
    21  	registerDBCreator(GoLevelDBBackendStr, dbCreator, false)
    22  }
    23  
    24  type GoLevelDB struct {
    25  	db *leveldb.DB
    26  }
    27  
    28  func NewGoLevelDB(name string, dir string) (*GoLevelDB, error) {
    29  	dbPath := path.Join(dir, name+".db")
    30  	db, err := leveldb.OpenFile(dbPath, nil)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	database := &GoLevelDB{db: db}
    35  	return database, nil
    36  }
    37  
    38  func (db *GoLevelDB) Get(key []byte) []byte {
    39  	res, err := db.db.Get(key, nil)
    40  	if err != nil {
    41  		if err == errors.ErrNotFound {
    42  			return nil
    43  		} else {
    44  			PanicCrisis(err)
    45  		}
    46  	}
    47  	return res
    48  }
    49  
    50  func (db *GoLevelDB) Set(key []byte, value []byte) {
    51  	err := db.db.Put(key, value, nil)
    52  	if err != nil {
    53  		PanicCrisis(err)
    54  	}
    55  }
    56  
    57  func (db *GoLevelDB) SetSync(key []byte, value []byte) {
    58  	err := db.db.Put(key, value, &opt.WriteOptions{Sync: true})
    59  	if err != nil {
    60  		PanicCrisis(err)
    61  	}
    62  }
    63  
    64  func (db *GoLevelDB) Delete(key []byte) {
    65  	err := db.db.Delete(key, nil)
    66  	if err != nil {
    67  		PanicCrisis(err)
    68  	}
    69  }
    70  
    71  func (db *GoLevelDB) DeleteSync(key []byte) {
    72  	err := db.db.Delete(key, &opt.WriteOptions{Sync: true})
    73  	if err != nil {
    74  		PanicCrisis(err)
    75  	}
    76  }
    77  
    78  func (db *GoLevelDB) DB() *leveldb.DB {
    79  	return db.db
    80  }
    81  
    82  func (db *GoLevelDB) Close() {
    83  	db.db.Close()
    84  }
    85  
    86  func (db *GoLevelDB) Print() {
    87  	str, _ := db.db.GetProperty("leveldb.stats")
    88  	fmt.Printf("%v\n", str)
    89  
    90  	iter := db.db.NewIterator(nil, nil)
    91  	for iter.Next() {
    92  		key := iter.Key()
    93  		value := iter.Value()
    94  		fmt.Printf("[%X]:\t[%X]\n", key, value)
    95  	}
    96  }
    97  
    98  func (db *GoLevelDB) Stats() map[string]string {
    99  	keys := []string{
   100  		"leveldb.num-files-at-level{n}",
   101  		"leveldb.stats",
   102  		"leveldb.sstables",
   103  		"leveldb.blockpool",
   104  		"leveldb.cachedblock",
   105  		"leveldb.openedtables",
   106  		"leveldb.alivesnaps",
   107  		"leveldb.aliveiters",
   108  	}
   109  
   110  	stats := make(map[string]string)
   111  	for _, key := range keys {
   112  		str, err := db.db.GetProperty(key)
   113  		if err == nil {
   114  			stats[key] = str
   115  		}
   116  	}
   117  	return stats
   118  }
   119  
   120  type goLevelDBIterator struct {
   121  	source    iterator.Iterator
   122  	start     []byte
   123  	isReverse bool
   124  }
   125  
   126  func newGoLevelDBIterator(source iterator.Iterator, start []byte, isReverse bool) *goLevelDBIterator {
   127  	if start != nil {
   128  		valid := source.Seek(start)
   129  		if !valid && isReverse {
   130  			source.Last()
   131  			source.Next()
   132  		}
   133  	} else if isReverse {
   134  		source.Last()
   135  		source.Next()
   136  	}
   137  
   138  	return &goLevelDBIterator{
   139  		source:    source,
   140  		start:     start,
   141  		isReverse: isReverse,
   142  	}
   143  }
   144  
   145  // Key returns a copy of the current key.
   146  func (it *goLevelDBIterator) Key() []byte {
   147  	key := it.source.Key()
   148  	k := make([]byte, len(key))
   149  	copy(k, key)
   150  
   151  	return k
   152  }
   153  
   154  // Value returns a copy of the current value.
   155  func (it *goLevelDBIterator) Value() []byte {
   156  	val := it.source.Value()
   157  	v := make([]byte, len(val))
   158  	copy(v, val)
   159  
   160  	return v
   161  }
   162  
   163  func (it *goLevelDBIterator) Seek(point []byte) bool {
   164  	return it.source.Seek(point)
   165  }
   166  
   167  func (it *goLevelDBIterator) Error() error {
   168  	return it.source.Error()
   169  }
   170  
   171  func (it *goLevelDBIterator) Next() bool {
   172  	it.assertNoError()
   173  	if it.isReverse {
   174  		return it.source.Prev()
   175  	}
   176  	return it.source.Next()
   177  }
   178  
   179  func (it *goLevelDBIterator) Release() {
   180  	it.source.Release()
   181  }
   182  
   183  func (it *goLevelDBIterator) assertNoError() {
   184  	if err := it.source.Error(); err != nil {
   185  		panic(err)
   186  	}
   187  }
   188  
   189  func (db *GoLevelDB) Iterator() Iterator {
   190  	return &goLevelDBIterator{source: db.db.NewIterator(nil, nil)}
   191  }
   192  
   193  func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator {
   194  	return &goLevelDBIterator{source: db.db.NewIterator(util.BytesPrefix(prefix), nil)}
   195  }
   196  
   197  func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator {
   198  	itr := db.db.NewIterator(util.BytesPrefix(Prefix), nil)
   199  	return newGoLevelDBIterator(itr, start, isReverse)
   200  }
   201  
   202  func (db *GoLevelDB) NewBatch() Batch {
   203  	batch := new(leveldb.Batch)
   204  	return &goLevelDBBatch{db, batch}
   205  }
   206  
   207  //--------------------------------------------------------------------------------
   208  
   209  type goLevelDBBatch struct {
   210  	db    *GoLevelDB
   211  	batch *leveldb.Batch
   212  }
   213  
   214  func (mBatch *goLevelDBBatch) Set(key, value []byte) {
   215  	mBatch.batch.Put(key, value)
   216  }
   217  
   218  func (mBatch *goLevelDBBatch) Delete(key []byte) {
   219  	mBatch.batch.Delete(key)
   220  }
   221  
   222  func (mBatch *goLevelDBBatch) Write() {
   223  	err := mBatch.db.db.Write(mBatch.batch, nil)
   224  	if err != nil {
   225  		PanicCrisis(err)
   226  	}
   227  }