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.

187 lines
3.7 KiB

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
9 years ago
9 years ago
9 years ago
9 years ago
  1. package db
  2. import (
  3. "fmt"
  4. "path"
  5. "github.com/syndtr/goleveldb/leveldb"
  6. "github.com/syndtr/goleveldb/leveldb/errors"
  7. "github.com/syndtr/goleveldb/leveldb/iterator"
  8. "github.com/syndtr/goleveldb/leveldb/opt"
  9. "github.com/syndtr/goleveldb/leveldb/util"
  10. . "github.com/tendermint/tmlibs/common"
  11. )
  12. func init() {
  13. dbCreator := func(name string, dir string) (DB, error) {
  14. return NewGoLevelDB(name, dir)
  15. }
  16. registerDBCreator(LevelDBBackendStr, dbCreator, false)
  17. registerDBCreator(GoLevelDBBackendStr, dbCreator, false)
  18. }
  19. type GoLevelDB struct {
  20. db *leveldb.DB
  21. }
  22. func NewGoLevelDB(name string, dir string) (*GoLevelDB, error) {
  23. dbPath := path.Join(dir, name+".db")
  24. db, err := leveldb.OpenFile(dbPath, nil)
  25. if err != nil {
  26. return nil, err
  27. }
  28. database := &GoLevelDB{db: db}
  29. return database, nil
  30. }
  31. func (db *GoLevelDB) Get(key []byte) []byte {
  32. res, err := db.db.Get(key, nil)
  33. if err != nil {
  34. if err == errors.ErrNotFound {
  35. return nil
  36. } else {
  37. PanicCrisis(err)
  38. }
  39. }
  40. return res
  41. }
  42. func (db *GoLevelDB) Set(key []byte, value []byte) {
  43. err := db.db.Put(key, value, nil)
  44. if err != nil {
  45. PanicCrisis(err)
  46. }
  47. }
  48. func (db *GoLevelDB) SetSync(key []byte, value []byte) {
  49. err := db.db.Put(key, value, &opt.WriteOptions{Sync: true})
  50. if err != nil {
  51. PanicCrisis(err)
  52. }
  53. }
  54. func (db *GoLevelDB) Delete(key []byte) {
  55. err := db.db.Delete(key, nil)
  56. if err != nil {
  57. PanicCrisis(err)
  58. }
  59. }
  60. func (db *GoLevelDB) DeleteSync(key []byte) {
  61. err := db.db.Delete(key, &opt.WriteOptions{Sync: true})
  62. if err != nil {
  63. PanicCrisis(err)
  64. }
  65. }
  66. func (db *GoLevelDB) DB() *leveldb.DB {
  67. return db.db
  68. }
  69. func (db *GoLevelDB) Close() {
  70. db.db.Close()
  71. }
  72. func (db *GoLevelDB) Print() {
  73. str, _ := db.db.GetProperty("leveldb.stats")
  74. fmt.Printf("%v\n", str)
  75. iter := db.db.NewIterator(nil, nil)
  76. for iter.Next() {
  77. key := iter.Key()
  78. value := iter.Value()
  79. fmt.Printf("[%X]:\t[%X]\n", key, value)
  80. }
  81. }
  82. func (db *GoLevelDB) Stats() map[string]string {
  83. keys := []string{
  84. "leveldb.num-files-at-level{n}",
  85. "leveldb.stats",
  86. "leveldb.sstables",
  87. "leveldb.blockpool",
  88. "leveldb.cachedblock",
  89. "leveldb.openedtables",
  90. "leveldb.alivesnaps",
  91. "leveldb.aliveiters",
  92. }
  93. stats := make(map[string]string)
  94. for _, key := range keys {
  95. str, err := db.db.GetProperty(key)
  96. if err == nil {
  97. stats[key] = str
  98. }
  99. }
  100. return stats
  101. }
  102. type goLevelDBIterator struct {
  103. source iterator.Iterator
  104. }
  105. // Key returns a copy of the current key.
  106. func (it *goLevelDBIterator) Key() []byte {
  107. key := it.source.Key()
  108. k := make([]byte, len(key))
  109. copy(k, key)
  110. return k
  111. }
  112. // Value returns a copy of the current value.
  113. func (it *goLevelDBIterator) Value() []byte {
  114. val := it.source.Value()
  115. v := make([]byte, len(val))
  116. copy(v, val)
  117. return v
  118. }
  119. func (it *goLevelDBIterator) Error() error {
  120. return it.source.Error()
  121. }
  122. func (it *goLevelDBIterator) Next() bool {
  123. return it.source.Next()
  124. }
  125. func (it *goLevelDBIterator) Release() {
  126. it.source.Release()
  127. }
  128. func (db *GoLevelDB) Iterator() Iterator {
  129. return &goLevelDBIterator{db.db.NewIterator(nil, nil)}
  130. }
  131. func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator {
  132. return &goLevelDBIterator{db.db.NewIterator(util.BytesPrefix(prefix), nil)}
  133. }
  134. func (db *GoLevelDB) NewBatch() Batch {
  135. batch := new(leveldb.Batch)
  136. return &goLevelDBBatch{db, batch}
  137. }
  138. //--------------------------------------------------------------------------------
  139. type goLevelDBBatch struct {
  140. db *GoLevelDB
  141. batch *leveldb.Batch
  142. }
  143. func (mBatch *goLevelDBBatch) Set(key, value []byte) {
  144. mBatch.batch.Put(key, value)
  145. }
  146. func (mBatch *goLevelDBBatch) Delete(key []byte) {
  147. mBatch.batch.Delete(key)
  148. }
  149. func (mBatch *goLevelDBBatch) Write() {
  150. err := mBatch.db.db.Write(mBatch.batch, nil)
  151. if err != nil {
  152. PanicCrisis(err)
  153. }
  154. }