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.

226 lines
4.1 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. // +build gcc
  2. package db
  3. import (
  4. "fmt"
  5. "path/filepath"
  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. var _ DB = (*CLevelDB)(nil)
  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 := filepath.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. panicNilKey(key)
  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) Has(key []byte) bool {
  52. panicNilKey(key)
  53. panic("not implemented yet")
  54. }
  55. func (db *CLevelDB) Set(key []byte, value []byte) {
  56. panicNilKey(key)
  57. err := db.db.Put(db.wo, key, value)
  58. if err != nil {
  59. panic(err)
  60. }
  61. }
  62. func (db *CLevelDB) SetSync(key []byte, value []byte) {
  63. panicNilKey(key)
  64. err := db.db.Put(db.woSync, key, value)
  65. if err != nil {
  66. panic(err)
  67. }
  68. }
  69. func (db *CLevelDB) Delete(key []byte) {
  70. panicNilKey(key)
  71. err := db.db.Delete(db.wo, key)
  72. if err != nil {
  73. panic(err)
  74. }
  75. }
  76. func (db *CLevelDB) DeleteSync(key []byte) {
  77. panicNilKey(key)
  78. err := db.db.Delete(db.woSync, key)
  79. if err != nil {
  80. panic(err)
  81. }
  82. }
  83. func (db *CLevelDB) DB() *levigo.DB {
  84. return db.db
  85. }
  86. func (db *CLevelDB) Close() {
  87. db.db.Close()
  88. db.ro.Close()
  89. db.wo.Close()
  90. db.woSync.Close()
  91. }
  92. func (db *CLevelDB) Print() {
  93. itr := db.Iterator(BeginningKey(), EndingKey())
  94. defer itr.Release()
  95. for ; itr.Valid(); itr.Next() {
  96. key := itr.Key()
  97. value := itr.Value()
  98. fmt.Printf("[%X]:\t[%X]\n", key, value)
  99. }
  100. }
  101. func (db *CLevelDB) Stats() map[string]string {
  102. // TODO: Find the available properties for the C LevelDB implementation
  103. keys := []string{}
  104. stats := make(map[string]string)
  105. for _, key := range keys {
  106. str := db.db.PropertyValue(key)
  107. stats[key] = str
  108. }
  109. return stats
  110. }
  111. //----------------------------------------
  112. // Batch
  113. func (db *CLevelDB) NewBatch() Batch {
  114. batch := levigo.NewWriteBatch()
  115. return &cLevelDBBatch{db, batch}
  116. }
  117. type cLevelDBBatch struct {
  118. db *CLevelDB
  119. batch *levigo.WriteBatch
  120. }
  121. func (mBatch *cLevelDBBatch) Set(key, value []byte) {
  122. mBatch.batch.Put(key, value)
  123. }
  124. func (mBatch *cLevelDBBatch) Delete(key []byte) {
  125. mBatch.batch.Delete(key)
  126. }
  127. func (mBatch *cLevelDBBatch) Write() {
  128. err := mBatch.db.db.Write(mBatch.db.wo, mBatch.batch)
  129. if err != nil {
  130. panic(err)
  131. }
  132. }
  133. //----------------------------------------
  134. // Iterator
  135. func (db *CLevelDB) Iterator(start, end []byte) Iterator {
  136. itr := db.db.NewIterator(db.ro)
  137. if len(start) > 0 {
  138. itr.Seek(start)
  139. } else {
  140. itr.SeekToFirst()
  141. }
  142. return cLevelDBIterator{
  143. itr: itr,
  144. start: start,
  145. end: end,
  146. }
  147. }
  148. func (db *CLevelDB) ReverseIterator(start, end []byte) Iterator {
  149. // XXX
  150. return nil
  151. }
  152. var _ Iterator = (*cLevelDBIterator)(nil)
  153. type cLevelDBIterator struct {
  154. itr *levigo.Iterator
  155. start, end []byte
  156. }
  157. func (c cLevelDBIterator) Domain() ([]byte, []byte) {
  158. return c.start, c.end
  159. }
  160. func (c cLevelDBIterator) Valid() bool {
  161. c.assertNoError()
  162. return c.itr.Valid()
  163. }
  164. func (c cLevelDBIterator) Key() []byte {
  165. if !c.itr.Valid() {
  166. panic("cLevelDBIterator Key() called when invalid")
  167. }
  168. return c.itr.Key()
  169. }
  170. func (c cLevelDBIterator) Value() []byte {
  171. if !c.itr.Valid() {
  172. panic("cLevelDBIterator Value() called when invalid")
  173. }
  174. return c.itr.Value()
  175. }
  176. func (c cLevelDBIterator) Next() {
  177. if !c.itr.Valid() {
  178. panic("cLevelDBIterator Next() called when invalid")
  179. }
  180. c.itr.Next()
  181. }
  182. func (c cLevelDBIterator) Release() {
  183. c.itr.Close()
  184. }
  185. func (c cLevelDBIterator) assertNoError() {
  186. if err := c.itr.GetError(); err != nil {
  187. panic(err)
  188. }
  189. }