OSDN Git Service

versoin1.1.9 (#594)
[bytom/vapor.git] / database / leveldb / go_level_db.go
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 }