github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/db/leveldb_store.go (about)

     1  /*
     2   * Copyright (C) 2018 The ontology Authors
     3   * This file is part of The ontology library.
     4   *
     5   * The ontology 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 ontology 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 ontology.  If not, see <http://www.gnu.org/licenses/>.
    17   */
    18  
    19  package db
    20  
    21  import (
    22  	"github.com/syndtr/goleveldb/leveldb"
    23  	"github.com/syndtr/goleveldb/leveldb/errors"
    24  	"github.com/syndtr/goleveldb/leveldb/filter"
    25  	"github.com/syndtr/goleveldb/leveldb/opt"
    26  	"github.com/syndtr/goleveldb/leveldb/util"
    27  	berrors "github.com/sixexorg/magnetic-ring/errors"
    28  )
    29  
    30  //LevelDB store
    31  type LevelDBStore struct {
    32  	db    *leveldb.DB // LevelDB instance
    33  	batch *leveldb.Batch
    34  }
    35  
    36  // used to compute the size of bloom filter bits array .
    37  // too small will lead to high false positive rate.
    38  const BITSPERKEY = 10
    39  
    40  //NewLevelDBStore return LevelDBStore instance
    41  func NewLevelDBStore(file string) (*LevelDBStore, error) {
    42  
    43  	// default Options
    44  	o := opt.Options{
    45  		NoSync: false,
    46  		Filter: filter.NewBloomFilter(BITSPERKEY),
    47  	}
    48  
    49  	db, err := leveldb.OpenFile(file, &o)
    50  
    51  	if _, corrupted := err.(*errors.ErrCorrupted); corrupted {
    52  		db, err = leveldb.RecoverFile(file, nil)
    53  	}
    54  
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	return &LevelDBStore{
    60  		db:    db,
    61  		batch: nil,
    62  	}, nil
    63  }
    64  
    65  //Put a key-value pair to leveldb
    66  func (self *LevelDBStore) Put(key []byte, value []byte) error {
    67  	return self.db.Put(key, value, nil)
    68  }
    69  
    70  //Get the value of a key from leveldb
    71  func (self *LevelDBStore) Get(key []byte) ([]byte, error) {
    72  	dat, err := self.db.Get(key, nil)
    73  	if err != nil {
    74  		if err == leveldb.ErrNotFound {
    75  			return nil, berrors.ERR_DB_NOT_FOUND
    76  		}
    77  		return nil, err
    78  	}
    79  	return dat, nil
    80  }
    81  
    82  //Has return whether the key is exist in leveldb
    83  func (self *LevelDBStore) Has(key []byte) (bool, error) {
    84  	return self.db.Has(key, nil)
    85  }
    86  
    87  //Delete the the in leveldb
    88  func (self *LevelDBStore) Delete(key []byte) error {
    89  	return self.db.Delete(key, nil)
    90  }
    91  
    92  //NewBatch start commit batch
    93  func (self *LevelDBStore) NewBatch() {
    94  	self.batch = new(leveldb.Batch)
    95  }
    96  
    97  //BatchPut put a key-value pair to leveldb batch
    98  func (self *LevelDBStore) BatchPut(key []byte, value []byte) {
    99  	self.batch.Put(key, value)
   100  }
   101  
   102  //BatchDelete delete a key to leveldb batch
   103  func (self *LevelDBStore) BatchDelete(key []byte) {
   104  	self.batch.Delete(key)
   105  }
   106  
   107  //BatchCommit commit batch to leveldb
   108  func (self *LevelDBStore) BatchCommit() error {
   109  	err := self.db.Write(self.batch, nil)
   110  	if err != nil {
   111  		return err
   112  	}
   113  	self.batch = nil
   114  	return nil
   115  }
   116  
   117  //Close leveldb
   118  func (self *LevelDBStore) Close() error {
   119  	err := self.db.Close()
   120  	return err
   121  }
   122  
   123  //NewIterator return a iterator of leveldb with the key perfix
   124  func (self *LevelDBStore) NewIterator(prefix []byte) *Iterator {
   125  
   126  	iter := self.db.NewIterator(util.BytesPrefix(prefix), nil)
   127  	return &Iterator{
   128  		iter: iter,
   129  	}
   130  }
   131  
   132  func (self *LevelDBStore) NewSeniorIterator(p *util.Range) *Iterator {
   133  	iter := self.db.NewIterator(p, nil)
   134  	return &Iterator{
   135  		iter: iter,
   136  	}
   137  }