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.

152 lines
2.9 KiB

  1. // +build gcc
  2. package db
  3. import (
  4. "fmt"
  5. "path"
  6. "github.com/jmhodges/levigo"
  7. . "github.com/tendermint/tmlibs/common"
  8. )
  9. func init() {
  10. dbCreator := func(name string, dir string) (DB, error) {
  11. return NewCLevelDB(name, dir)
  12. }
  13. registerDBCreator(LevelDBBackendStr, dbCreator, true)
  14. registerDBCreator(CLevelDBBackendStr, dbCreator, false)
  15. }
  16. type CLevelDB struct {
  17. db *levigo.DB
  18. ro *levigo.ReadOptions
  19. wo *levigo.WriteOptions
  20. woSync *levigo.WriteOptions
  21. }
  22. func NewCLevelDB(name string, dir string) (*CLevelDB, error) {
  23. dbPath := path.Join(dir, name+".db")
  24. opts := levigo.NewOptions()
  25. opts.SetCache(levigo.NewLRUCache(1 << 30))
  26. opts.SetCreateIfMissing(true)
  27. db, err := levigo.Open(dbPath, opts)
  28. if err != nil {
  29. return nil, err
  30. }
  31. ro := levigo.NewReadOptions()
  32. wo := levigo.NewWriteOptions()
  33. woSync := levigo.NewWriteOptions()
  34. woSync.SetSync(true)
  35. database := &CLevelDB{
  36. db: db,
  37. ro: ro,
  38. wo: wo,
  39. woSync: woSync,
  40. }
  41. return database, nil
  42. }
  43. func (db *CLevelDB) Get(key []byte) []byte {
  44. res, err := db.db.Get(db.ro, key)
  45. if err != nil {
  46. PanicCrisis(err)
  47. }
  48. return res
  49. }
  50. func (db *CLevelDB) Set(key []byte, value []byte) {
  51. err := db.db.Put(db.wo, key, value)
  52. if err != nil {
  53. PanicCrisis(err)
  54. }
  55. }
  56. func (db *CLevelDB) SetSync(key []byte, value []byte) {
  57. err := db.db.Put(db.woSync, key, value)
  58. if err != nil {
  59. PanicCrisis(err)
  60. }
  61. }
  62. func (db *CLevelDB) Delete(key []byte) {
  63. err := db.db.Delete(db.wo, key)
  64. if err != nil {
  65. PanicCrisis(err)
  66. }
  67. }
  68. func (db *CLevelDB) DeleteSync(key []byte) {
  69. err := db.db.Delete(db.woSync, key)
  70. if err != nil {
  71. PanicCrisis(err)
  72. }
  73. }
  74. func (db *CLevelDB) DB() *levigo.DB {
  75. return db.db
  76. }
  77. func (db *CLevelDB) Close() {
  78. db.db.Close()
  79. db.ro.Close()
  80. db.wo.Close()
  81. db.woSync.Close()
  82. }
  83. func (db *CLevelDB) Print() {
  84. iter := db.db.NewIterator(db.ro)
  85. defer iter.Close()
  86. for iter.Seek(nil); iter.Valid(); iter.Next() {
  87. key := iter.Key()
  88. value := iter.Value()
  89. fmt.Printf("[%X]:\t[%X]\n", key, value)
  90. }
  91. }
  92. func (db *CLevelDB) Stats() map[string]string {
  93. // TODO: Find the available properties for the C LevelDB implementation
  94. keys := []string{}
  95. stats := make(map[string]string)
  96. for _, key := range keys {
  97. str, err := db.db.GetProperty(key)
  98. if err == nil {
  99. stats[key] = str
  100. }
  101. }
  102. return stats
  103. }
  104. func (db *CLevelDB) Iterator() Iterator {
  105. return db.db.NewIterator(nil, nil)
  106. }
  107. func (db *CLevelDB) NewBatch() Batch {
  108. batch := levigo.NewWriteBatch()
  109. return &cLevelDBBatch{db, batch}
  110. }
  111. //--------------------------------------------------------------------------------
  112. type cLevelDBBatch struct {
  113. db *CLevelDB
  114. batch *levigo.WriteBatch
  115. }
  116. func (mBatch *cLevelDBBatch) Set(key, value []byte) {
  117. mBatch.batch.Put(key, value)
  118. }
  119. func (mBatch *cLevelDBBatch) Delete(key []byte) {
  120. mBatch.batch.Delete(key)
  121. }
  122. func (mBatch *cLevelDBBatch) Write() {
  123. err := mBatch.db.db.Write(mBatch.db.wo, mBatch.batch)
  124. if err != nil {
  125. PanicCrisis(err)
  126. }
  127. }