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 }