|
- package nodb
-
- import (
- "fmt"
- "sync"
-
- "github.com/lunny/nodb/store"
- )
-
- type ibucket interface {
- Get(key []byte) ([]byte, error)
-
- Put(key []byte, value []byte) error
- Delete(key []byte) error
-
- NewIterator() *store.Iterator
-
- NewWriteBatch() store.WriteBatch
-
- RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
- RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
- RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
- RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
- }
-
- type DB struct {
- l *Nodb
-
- sdb *store.DB
-
- bucket ibucket
-
- index uint8
-
- kvBatch *batch
- listBatch *batch
- hashBatch *batch
- zsetBatch *batch
- binBatch *batch
- setBatch *batch
-
- status uint8
- }
-
- func (l *Nodb) newDB(index uint8) *DB {
- d := new(DB)
-
- d.l = l
-
- d.sdb = l.ldb
-
- d.bucket = d.sdb
-
- d.status = DBAutoCommit
- d.index = index
-
- d.kvBatch = d.newBatch()
- d.listBatch = d.newBatch()
- d.hashBatch = d.newBatch()
- d.zsetBatch = d.newBatch()
- d.binBatch = d.newBatch()
- d.setBatch = d.newBatch()
-
- return d
- }
-
- func (db *DB) newBatch() *batch {
- return db.l.newBatch(db.bucket.NewWriteBatch(), &dbBatchLocker{l: &sync.Mutex{}, wrLock: &db.l.wLock}, nil)
- }
-
- func (db *DB) Index() int {
- return int(db.index)
- }
-
- func (db *DB) IsAutoCommit() bool {
- return db.status == DBAutoCommit
- }
-
- func (db *DB) FlushAll() (drop int64, err error) {
- all := [...](func() (int64, error)){
- db.flush,
- db.lFlush,
- db.hFlush,
- db.zFlush,
- db.bFlush,
- db.sFlush}
-
- for _, flush := range all {
- if n, e := flush(); e != nil {
- err = e
- return
- } else {
- drop += n
- }
- }
-
- return
- }
-
- func (db *DB) newEliminator() *elimination {
- eliminator := newEliminator(db)
-
- eliminator.regRetireContext(KVType, db.kvBatch, db.delete)
- eliminator.regRetireContext(ListType, db.listBatch, db.lDelete)
- eliminator.regRetireContext(HashType, db.hashBatch, db.hDelete)
- eliminator.regRetireContext(ZSetType, db.zsetBatch, db.zDelete)
- eliminator.regRetireContext(BitType, db.binBatch, db.bDelete)
- eliminator.regRetireContext(SetType, db.setBatch, db.sDelete)
-
- return eliminator
- }
-
- func (db *DB) flushRegion(t *batch, minKey []byte, maxKey []byte) (drop int64, err error) {
- it := db.bucket.RangeIterator(minKey, maxKey, store.RangeROpen)
- for ; it.Valid(); it.Next() {
- t.Delete(it.RawKey())
- drop++
- if drop&1023 == 0 {
- if err = t.Commit(); err != nil {
- return
- }
- }
- }
- it.Close()
- return
- }
-
- func (db *DB) flushType(t *batch, dataType byte) (drop int64, err error) {
- var deleteFunc func(t *batch, key []byte) int64
- var metaDataType byte
- switch dataType {
- case KVType:
- deleteFunc = db.delete
- metaDataType = KVType
- case ListType:
- deleteFunc = db.lDelete
- metaDataType = LMetaType
- case HashType:
- deleteFunc = db.hDelete
- metaDataType = HSizeType
- case ZSetType:
- deleteFunc = db.zDelete
- metaDataType = ZSizeType
- case BitType:
- deleteFunc = db.bDelete
- metaDataType = BitMetaType
- case SetType:
- deleteFunc = db.sDelete
- metaDataType = SSizeType
- default:
- return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType])
- }
-
- var keys [][]byte
- keys, err = db.scan(metaDataType, nil, 1024, false, "")
- for len(keys) != 0 || err != nil {
- for _, key := range keys {
- deleteFunc(t, key)
- db.rmExpire(t, dataType, key)
-
- }
-
- if err = t.Commit(); err != nil {
- return
- } else {
- drop += int64(len(keys))
- }
- keys, err = db.scan(metaDataType, nil, 1024, false, "")
- }
- return
- }
|