You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
6.8 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package db
  2. import (
  3. "bytes"
  4. "fmt"
  5. "path/filepath"
  6. "github.com/syndtr/goleveldb/leveldb"
  7. "github.com/syndtr/goleveldb/leveldb/errors"
  8. "github.com/syndtr/goleveldb/leveldb/iterator"
  9. "github.com/syndtr/goleveldb/leveldb/opt"
  10. cmn "github.com/tendermint/tendermint/libs/common"
  11. )
  12. func init() {
  13. dbCreator := func(name string, dir string) (DB, error) {
  14. return NewGoLevelDB(name, dir)
  15. }
  16. registerDBCreator(LevelDBBackend, dbCreator, false)
  17. registerDBCreator(GoLevelDBBackend, dbCreator, false)
  18. }
  19. var _ DB = (*GoLevelDB)(nil)
  20. type GoLevelDB struct {
  21. db *leveldb.DB
  22. }
  23. func NewGoLevelDB(name string, dir string) (*GoLevelDB, error) {
  24. return NewGoLevelDBWithOpts(name, dir, nil)
  25. }
  26. func NewGoLevelDBWithOpts(name string, dir string, o *opt.Options) (*GoLevelDB, error) {
  27. dbPath := filepath.Join(dir, name+".db")
  28. db, err := leveldb.OpenFile(dbPath, o)
  29. if err != nil {
  30. return nil, err
  31. }
  32. database := &GoLevelDB{
  33. db: db,
  34. }
  35. return database, nil
  36. }
  37. // Implements DB.
  38. func (db *GoLevelDB) Get(key []byte) []byte {
  39. key = nonNilBytes(key)
  40. res, err := db.db.Get(key, nil)
  41. if err != nil {
  42. if err == errors.ErrNotFound {
  43. return nil
  44. }
  45. panic(err)
  46. }
  47. return res
  48. }
  49. // Implements DB.
  50. func (db *GoLevelDB) Has(key []byte) bool {
  51. return db.Get(key) != nil
  52. }
  53. // Implements DB.
  54. func (db *GoLevelDB) Set(key []byte, value []byte) {
  55. key = nonNilBytes(key)
  56. value = nonNilBytes(value)
  57. err := db.db.Put(key, value, nil)
  58. if err != nil {
  59. cmn.PanicCrisis(err)
  60. }
  61. }
  62. // Implements DB.
  63. func (db *GoLevelDB) SetSync(key []byte, value []byte) {
  64. key = nonNilBytes(key)
  65. value = nonNilBytes(value)
  66. err := db.db.Put(key, value, &opt.WriteOptions{Sync: true})
  67. if err != nil {
  68. cmn.PanicCrisis(err)
  69. }
  70. }
  71. // Implements DB.
  72. func (db *GoLevelDB) Delete(key []byte) {
  73. key = nonNilBytes(key)
  74. err := db.db.Delete(key, nil)
  75. if err != nil {
  76. cmn.PanicCrisis(err)
  77. }
  78. }
  79. // Implements DB.
  80. func (db *GoLevelDB) DeleteSync(key []byte) {
  81. key = nonNilBytes(key)
  82. err := db.db.Delete(key, &opt.WriteOptions{Sync: true})
  83. if err != nil {
  84. cmn.PanicCrisis(err)
  85. }
  86. }
  87. func (db *GoLevelDB) DB() *leveldb.DB {
  88. return db.db
  89. }
  90. // Implements DB.
  91. func (db *GoLevelDB) Close() {
  92. db.db.Close()
  93. }
  94. // Implements DB.
  95. func (db *GoLevelDB) Print() {
  96. str, _ := db.db.GetProperty("leveldb.stats")
  97. fmt.Printf("%v\n", str)
  98. itr := db.db.NewIterator(nil, nil)
  99. for itr.Next() {
  100. key := itr.Key()
  101. value := itr.Value()
  102. fmt.Printf("[%X]:\t[%X]\n", key, value)
  103. }
  104. }
  105. // Implements DB.
  106. func (db *GoLevelDB) Stats() map[string]string {
  107. keys := []string{
  108. "leveldb.num-files-at-level{n}",
  109. "leveldb.stats",
  110. "leveldb.sstables",
  111. "leveldb.blockpool",
  112. "leveldb.cachedblock",
  113. "leveldb.openedtables",
  114. "leveldb.alivesnaps",
  115. "leveldb.aliveiters",
  116. }
  117. stats := make(map[string]string)
  118. for _, key := range keys {
  119. str, err := db.db.GetProperty(key)
  120. if err == nil {
  121. stats[key] = str
  122. }
  123. }
  124. return stats
  125. }
  126. //----------------------------------------
  127. // Batch
  128. // Implements DB.
  129. func (db *GoLevelDB) NewBatch() Batch {
  130. batch := new(leveldb.Batch)
  131. return &goLevelDBBatch{db, batch}
  132. }
  133. type goLevelDBBatch struct {
  134. db *GoLevelDB
  135. batch *leveldb.Batch
  136. }
  137. // Implements Batch.
  138. func (mBatch *goLevelDBBatch) Set(key, value []byte) {
  139. mBatch.batch.Put(key, value)
  140. }
  141. // Implements Batch.
  142. func (mBatch *goLevelDBBatch) Delete(key []byte) {
  143. mBatch.batch.Delete(key)
  144. }
  145. // Implements Batch.
  146. func (mBatch *goLevelDBBatch) Write() {
  147. err := mBatch.db.db.Write(mBatch.batch, &opt.WriteOptions{Sync: false})
  148. if err != nil {
  149. panic(err)
  150. }
  151. }
  152. // Implements Batch.
  153. func (mBatch *goLevelDBBatch) WriteSync() {
  154. err := mBatch.db.db.Write(mBatch.batch, &opt.WriteOptions{Sync: true})
  155. if err != nil {
  156. panic(err)
  157. }
  158. }
  159. // Implements Batch.
  160. // Close is no-op for goLevelDBBatch.
  161. func (mBatch *goLevelDBBatch) Close() {}
  162. //----------------------------------------
  163. // Iterator
  164. // NOTE This is almost identical to db/c_level_db.Iterator
  165. // Before creating a third version, refactor.
  166. // Implements DB.
  167. func (db *GoLevelDB) Iterator(start, end []byte) Iterator {
  168. itr := db.db.NewIterator(nil, nil)
  169. return newGoLevelDBIterator(itr, start, end, false)
  170. }
  171. // Implements DB.
  172. func (db *GoLevelDB) ReverseIterator(start, end []byte) Iterator {
  173. itr := db.db.NewIterator(nil, nil)
  174. return newGoLevelDBIterator(itr, start, end, true)
  175. }
  176. type goLevelDBIterator struct {
  177. source iterator.Iterator
  178. start []byte
  179. end []byte
  180. isReverse bool
  181. isInvalid bool
  182. }
  183. var _ Iterator = (*goLevelDBIterator)(nil)
  184. func newGoLevelDBIterator(source iterator.Iterator, start, end []byte, isReverse bool) *goLevelDBIterator {
  185. if isReverse {
  186. if end == nil {
  187. source.Last()
  188. } else {
  189. valid := source.Seek(end)
  190. if valid {
  191. eoakey := source.Key() // end or after key
  192. if bytes.Compare(end, eoakey) <= 0 {
  193. source.Prev()
  194. }
  195. } else {
  196. source.Last()
  197. }
  198. }
  199. } else {
  200. if start == nil {
  201. source.First()
  202. } else {
  203. source.Seek(start)
  204. }
  205. }
  206. return &goLevelDBIterator{
  207. source: source,
  208. start: start,
  209. end: end,
  210. isReverse: isReverse,
  211. isInvalid: false,
  212. }
  213. }
  214. // Implements Iterator.
  215. func (itr *goLevelDBIterator) Domain() ([]byte, []byte) {
  216. return itr.start, itr.end
  217. }
  218. // Implements Iterator.
  219. func (itr *goLevelDBIterator) Valid() bool {
  220. // Once invalid, forever invalid.
  221. if itr.isInvalid {
  222. return false
  223. }
  224. // Panic on DB error. No way to recover.
  225. itr.assertNoError()
  226. // If source is invalid, invalid.
  227. if !itr.source.Valid() {
  228. itr.isInvalid = true
  229. return false
  230. }
  231. // If key is end or past it, invalid.
  232. var start = itr.start
  233. var end = itr.end
  234. var key = itr.source.Key()
  235. if itr.isReverse {
  236. if start != nil && bytes.Compare(key, start) < 0 {
  237. itr.isInvalid = true
  238. return false
  239. }
  240. } else {
  241. if end != nil && bytes.Compare(end, key) <= 0 {
  242. itr.isInvalid = true
  243. return false
  244. }
  245. }
  246. // Valid
  247. return true
  248. }
  249. // Implements Iterator.
  250. func (itr *goLevelDBIterator) Key() []byte {
  251. // Key returns a copy of the current key.
  252. // See https://github.com/syndtr/goleveldb/blob/52c212e6c196a1404ea59592d3f1c227c9f034b2/leveldb/iterator/iter.go#L88
  253. itr.assertNoError()
  254. itr.assertIsValid()
  255. return cp(itr.source.Key())
  256. }
  257. // Implements Iterator.
  258. func (itr *goLevelDBIterator) Value() []byte {
  259. // Value returns a copy of the current value.
  260. // See https://github.com/syndtr/goleveldb/blob/52c212e6c196a1404ea59592d3f1c227c9f034b2/leveldb/iterator/iter.go#L88
  261. itr.assertNoError()
  262. itr.assertIsValid()
  263. return cp(itr.source.Value())
  264. }
  265. // Implements Iterator.
  266. func (itr *goLevelDBIterator) Next() {
  267. itr.assertNoError()
  268. itr.assertIsValid()
  269. if itr.isReverse {
  270. itr.source.Prev()
  271. } else {
  272. itr.source.Next()
  273. }
  274. }
  275. // Implements Iterator.
  276. func (itr *goLevelDBIterator) Close() {
  277. itr.source.Release()
  278. }
  279. func (itr *goLevelDBIterator) assertNoError() {
  280. if err := itr.source.Error(); err != nil {
  281. panic(err)
  282. }
  283. }
  284. func (itr goLevelDBIterator) assertIsValid() {
  285. if !itr.Valid() {
  286. panic("goLevelDBIterator is invalid")
  287. }
  288. }