本站源代码
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.

172 lines
3.5KB

  1. package nodb
  2. import (
  3. "fmt"
  4. "sync"
  5. "github.com/lunny/nodb/store"
  6. )
  7. type ibucket interface {
  8. Get(key []byte) ([]byte, error)
  9. Put(key []byte, value []byte) error
  10. Delete(key []byte) error
  11. NewIterator() *store.Iterator
  12. NewWriteBatch() store.WriteBatch
  13. RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
  14. RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
  15. RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
  16. RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
  17. }
  18. type DB struct {
  19. l *Nodb
  20. sdb *store.DB
  21. bucket ibucket
  22. index uint8
  23. kvBatch *batch
  24. listBatch *batch
  25. hashBatch *batch
  26. zsetBatch *batch
  27. binBatch *batch
  28. setBatch *batch
  29. status uint8
  30. }
  31. func (l *Nodb) newDB(index uint8) *DB {
  32. d := new(DB)
  33. d.l = l
  34. d.sdb = l.ldb
  35. d.bucket = d.sdb
  36. d.status = DBAutoCommit
  37. d.index = index
  38. d.kvBatch = d.newBatch()
  39. d.listBatch = d.newBatch()
  40. d.hashBatch = d.newBatch()
  41. d.zsetBatch = d.newBatch()
  42. d.binBatch = d.newBatch()
  43. d.setBatch = d.newBatch()
  44. return d
  45. }
  46. func (db *DB) newBatch() *batch {
  47. return db.l.newBatch(db.bucket.NewWriteBatch(), &dbBatchLocker{l: &sync.Mutex{}, wrLock: &db.l.wLock}, nil)
  48. }
  49. func (db *DB) Index() int {
  50. return int(db.index)
  51. }
  52. func (db *DB) IsAutoCommit() bool {
  53. return db.status == DBAutoCommit
  54. }
  55. func (db *DB) FlushAll() (drop int64, err error) {
  56. all := [...](func() (int64, error)){
  57. db.flush,
  58. db.lFlush,
  59. db.hFlush,
  60. db.zFlush,
  61. db.bFlush,
  62. db.sFlush}
  63. for _, flush := range all {
  64. if n, e := flush(); e != nil {
  65. err = e
  66. return
  67. } else {
  68. drop += n
  69. }
  70. }
  71. return
  72. }
  73. func (db *DB) newEliminator() *elimination {
  74. eliminator := newEliminator(db)
  75. eliminator.regRetireContext(KVType, db.kvBatch, db.delete)
  76. eliminator.regRetireContext(ListType, db.listBatch, db.lDelete)
  77. eliminator.regRetireContext(HashType, db.hashBatch, db.hDelete)
  78. eliminator.regRetireContext(ZSetType, db.zsetBatch, db.zDelete)
  79. eliminator.regRetireContext(BitType, db.binBatch, db.bDelete)
  80. eliminator.regRetireContext(SetType, db.setBatch, db.sDelete)
  81. return eliminator
  82. }
  83. func (db *DB) flushRegion(t *batch, minKey []byte, maxKey []byte) (drop int64, err error) {
  84. it := db.bucket.RangeIterator(minKey, maxKey, store.RangeROpen)
  85. for ; it.Valid(); it.Next() {
  86. t.Delete(it.RawKey())
  87. drop++
  88. if drop&1023 == 0 {
  89. if err = t.Commit(); err != nil {
  90. return
  91. }
  92. }
  93. }
  94. it.Close()
  95. return
  96. }
  97. func (db *DB) flushType(t *batch, dataType byte) (drop int64, err error) {
  98. var deleteFunc func(t *batch, key []byte) int64
  99. var metaDataType byte
  100. switch dataType {
  101. case KVType:
  102. deleteFunc = db.delete
  103. metaDataType = KVType
  104. case ListType:
  105. deleteFunc = db.lDelete
  106. metaDataType = LMetaType
  107. case HashType:
  108. deleteFunc = db.hDelete
  109. metaDataType = HSizeType
  110. case ZSetType:
  111. deleteFunc = db.zDelete
  112. metaDataType = ZSizeType
  113. case BitType:
  114. deleteFunc = db.bDelete
  115. metaDataType = BitMetaType
  116. case SetType:
  117. deleteFunc = db.sDelete
  118. metaDataType = SSizeType
  119. default:
  120. return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType])
  121. }
  122. var keys [][]byte
  123. keys, err = db.scan(metaDataType, nil, 1024, false, "")
  124. for len(keys) != 0 || err != nil {
  125. for _, key := range keys {
  126. deleteFunc(t, key)
  127. db.rmExpire(t, dataType, key)
  128. }
  129. if err = t.Commit(); err != nil {
  130. return
  131. } else {
  132. drop += int64(len(keys))
  133. }
  134. keys, err = db.scan(metaDataType, nil, 1024, false, "")
  135. }
  136. return
  137. }
上海开阖软件有限公司 沪ICP备12045867号-1