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.

213 lines
3.9 KiB

  1. // +build gcc
  2. package db
  3. import (
  4. "fmt"
  5. "path"
  6. "github.com/jmhodges/levigo"
  7. )
  8. func init() {
  9. dbCreator := func(name string, dir string) (DB, error) {
  10. return NewCLevelDB(name, dir)
  11. }
  12. registerDBCreator(LevelDBBackendStr, dbCreator, true)
  13. registerDBCreator(CLevelDBBackendStr, dbCreator, false)
  14. }
  15. type CLevelDB struct {
  16. db *levigo.DB
  17. ro *levigo.ReadOptions
  18. wo *levigo.WriteOptions
  19. woSync *levigo.WriteOptions
  20. cwwMutex
  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. cwwMutex: NewCWWMutex(),
  41. }
  42. return database, nil
  43. }
  44. func (db *CLevelDB) Get(key []byte) []byte {
  45. res, err := db.db.Get(db.ro, key)
  46. if err != nil {
  47. panic(err)
  48. }
  49. return res
  50. }
  51. func (db *CLevelDB) Set(key []byte, value []byte) {
  52. err := db.db.Put(db.wo, key, value)
  53. if err != nil {
  54. panic(err)
  55. }
  56. }
  57. func (db *CLevelDB) SetSync(key []byte, value []byte) {
  58. err := db.db.Put(db.woSync, key, value)
  59. if err != nil {
  60. panic(err)
  61. }
  62. }
  63. func (db *CLevelDB) Delete(key []byte) {
  64. err := db.db.Delete(db.wo, key)
  65. if err != nil {
  66. panic(err)
  67. }
  68. }
  69. func (db *CLevelDB) DeleteSync(key []byte) {
  70. err := db.db.Delete(db.woSync, key)
  71. if err != nil {
  72. panic(err)
  73. }
  74. }
  75. func (db *CLevelDB) DB() *levigo.DB {
  76. return db.db
  77. }
  78. func (db *CLevelDB) Close() {
  79. db.db.Close()
  80. db.ro.Close()
  81. db.wo.Close()
  82. db.woSync.Close()
  83. }
  84. func (db *CLevelDB) Print() {
  85. itr := db.Iterator()
  86. defer itr.Close()
  87. for itr.Seek(nil); itr.Valid(); itr.Next() {
  88. key := itr.Key()
  89. value := itr.Value()
  90. fmt.Printf("[%X]:\t[%X]\n", key, value)
  91. }
  92. }
  93. func (db *CLevelDB) Stats() map[string]string {
  94. // TODO: Find the available properties for the C LevelDB implementation
  95. keys := []string{}
  96. stats := make(map[string]string)
  97. for _, key := range keys {
  98. str := db.db.PropertyValue(key)
  99. stats[key] = str
  100. }
  101. return stats
  102. }
  103. func (db *CLevelDB) CacheDB() CacheDB {
  104. return NewCacheDB(db, db.GetWriteLockVersion())
  105. }
  106. //----------------------------------------
  107. // Batch
  108. func (db *CLevelDB) NewBatch() Batch {
  109. batch := levigo.NewWriteBatch()
  110. return &cLevelDBBatch{db, batch}
  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. panic(err)
  126. }
  127. }
  128. //----------------------------------------
  129. // Iterator
  130. func (db *CLevelDB) Iterator() Iterator {
  131. itr := db.db.NewIterator(db.ro)
  132. itr.Seek([]byte{0x00})
  133. return cLevelDBIterator{itr}
  134. }
  135. type cLevelDBIterator struct {
  136. itr *levigo.Iterator
  137. }
  138. func (c cLevelDBIterator) Seek(key []byte) {
  139. if key == nil {
  140. key = []byte{0x00}
  141. }
  142. c.itr.Seek(key)
  143. }
  144. func (c cLevelDBIterator) Valid() bool {
  145. return c.itr.Valid()
  146. }
  147. func (c cLevelDBIterator) Key() []byte {
  148. if !c.itr.Valid() {
  149. panic("cLevelDBIterator Key() called when invalid")
  150. }
  151. return c.itr.Key()
  152. }
  153. func (c cLevelDBIterator) Value() []byte {
  154. if !c.itr.Valid() {
  155. panic("cLevelDBIterator Value() called when invalid")
  156. }
  157. return c.itr.Value()
  158. }
  159. func (c cLevelDBIterator) Next() {
  160. if !c.itr.Valid() {
  161. panic("cLevelDBIterator Next() called when invalid")
  162. }
  163. c.itr.Next()
  164. }
  165. func (c cLevelDBIterator) Prev() {
  166. if !c.itr.Valid() {
  167. panic("cLevelDBIterator Prev() called when invalid")
  168. }
  169. c.itr.Prev()
  170. }
  171. func (c cLevelDBIterator) Close() {
  172. c.itr.Close()
  173. }
  174. func (c cLevelDBIterator) GetError() error {
  175. return c.itr.GetError()
  176. }