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.

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