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.

333 lines
6.7 KiB

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