forked from mirror/ledisdb
update, can not run at all
This commit is contained in:
parent
8b8745be92
commit
8c70bbfdbe
|
@ -15,3 +15,5 @@ go get github.com/ugorji/go/codec
|
|||
go get github.com/BurntSushi/toml
|
||||
|
||||
go get github.com/siddontang/go-bson/bson
|
||||
|
||||
go get github.com/siddontang/go/num
|
||||
|
|
|
@ -20,29 +20,52 @@ type batch struct {
|
|||
}
|
||||
|
||||
func (b *batch) Commit() error {
|
||||
if b.l.replMode {
|
||||
return ErrWriteInReplMode
|
||||
}
|
||||
|
||||
b.l.commitLock.Lock()
|
||||
defer b.l.commitLock.Unlock()
|
||||
|
||||
if b.LogEanbled() {
|
||||
|
||||
}
|
||||
|
||||
err := b.WriteBatch.Commit()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// only use in expire cycle
|
||||
func (b *batch) expireCommit() error {
|
||||
b.l.commitLock.Lock()
|
||||
defer b.l.commitLock.Unlock()
|
||||
|
||||
return b.WriteBatch.Commit()
|
||||
}
|
||||
|
||||
func (b *batch) Lock() {
|
||||
b.Locker.Lock()
|
||||
}
|
||||
|
||||
func (b *batch) Unlock() {
|
||||
b.noLogging = false
|
||||
b.eb.Reset()
|
||||
b.WriteBatch.Rollback()
|
||||
b.Locker.Unlock()
|
||||
}
|
||||
|
||||
func (b *batch) Put(key []byte, value []byte) {
|
||||
if b.LogEanbled() {
|
||||
b.eb.Put(key, value)
|
||||
}
|
||||
b.WriteBatch.Put(key, value)
|
||||
}
|
||||
|
||||
func (b *batch) Delete(key []byte) {
|
||||
if b.LogEanbled() {
|
||||
b.eb.Delete(key)
|
||||
}
|
||||
|
||||
b.WriteBatch.Delete(key)
|
||||
}
|
||||
|
@ -51,8 +74,9 @@ func (b *batch) LogEanbled() bool {
|
|||
return !b.noLogging && b.l.log != nil
|
||||
}
|
||||
|
||||
func (b *batch) DisableLog(d bool) {
|
||||
b.noLogging = d
|
||||
// only for expire cycle
|
||||
func (b *batch) disableLog() {
|
||||
b.noLogging = true
|
||||
}
|
||||
|
||||
type dbBatchLocker struct {
|
||||
|
@ -90,7 +114,11 @@ func (l *Ledis) newBatch(wb store.WriteBatch, locker sync.Locker, tx *Tx) *batch
|
|||
b.tx = tx
|
||||
b.Locker = locker
|
||||
|
||||
b.eb = new(eventBatch)
|
||||
if tx != nil {
|
||||
b.eb = tx.eb
|
||||
} else {
|
||||
b.eb = new(eventBatch)
|
||||
}
|
||||
b.noLogging = false
|
||||
|
||||
return b
|
||||
|
|
|
@ -23,6 +23,8 @@ const (
|
|||
|
||||
ExpTimeType byte = 101
|
||||
ExpMetaType byte = 102
|
||||
|
||||
MetaType byte = 201
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -78,7 +80,8 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrScoreMiss = errors.New("zset score miss")
|
||||
ErrScoreMiss = errors.New("zset score miss")
|
||||
ErrWriteInReplMode = errors.New("write in replication mode")
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -24,7 +24,7 @@ type Ledis struct {
|
|||
wLock sync.RWMutex //allow one write at same time
|
||||
commitLock sync.Mutex //allow one write commit at same time
|
||||
|
||||
readOnly bool
|
||||
replMode bool
|
||||
}
|
||||
|
||||
func Open(cfg *config.Config) (*Ledis, error) {
|
||||
|
@ -89,9 +89,10 @@ func (l *Ledis) FlushAll() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// very dangerous to use
|
||||
func (l *Ledis) DataDB() *store.DB {
|
||||
return l.ldb
|
||||
// for replication mode, any write operations will fail,
|
||||
// except clear expired data in expire cycle
|
||||
func (l *Ledis) SetReplictionMode(b bool) {
|
||||
l.replMode = b
|
||||
}
|
||||
|
||||
func (l *Ledis) activeExpireCycle() {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package ledis
|
||||
|
||||
import (
|
||||
"github.com/siddontang/go/num"
|
||||
)
|
||||
|
||||
var (
|
||||
lastCommitIDKey = []byte{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
f := func(name string) []byte {
|
||||
b := make([]byte, 0, 2+len(name))
|
||||
b = append(b, []byte{255, MetaType}...)
|
||||
b = append(b, name...)
|
||||
return b
|
||||
}
|
||||
|
||||
lastCommitIDKey = f("last_commit_id")
|
||||
}
|
||||
|
||||
func (l *Ledis) GetLastCommitID() (uint64, error) {
|
||||
return Uint64(l.ldb.Get(lastCommitIDKey))
|
||||
}
|
||||
|
||||
func (l *Ledis) GetLastLogID() (uint64, error) {
|
||||
if l.log == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return l.log.LastID()
|
||||
}
|
||||
|
||||
func setLastCommitID(t *batch, id uint64) {
|
||||
t.Put(lastCommitIDKey, num.Uint64ToBytes(id))
|
||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"github.com/siddontang/go-log/log"
|
||||
"github.com/siddontang/ledisdb/store/driver"
|
||||
"github.com/siddontang/ledisdb/store"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
@ -26,7 +26,7 @@ var (
|
|||
)
|
||||
|
||||
type replBatch struct {
|
||||
wb driver.IWriteBatch
|
||||
wb store.WriteBatch
|
||||
events [][]byte
|
||||
l *Ledis
|
||||
|
||||
|
|
|
@ -24,17 +24,17 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match s
|
|||
if err = checkKeySize(key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
|
||||
if minKey, err = db.encodeScanKey(dataType, key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
if minKey, err = db.encodeMinKey(dataType); err != nil {
|
||||
if minKey, err = db.encodeScanMinKey(dataType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if maxKey, err = db.encodeMaxKey(dataType); err != nil {
|
||||
if maxKey, err = db.encodeScanMaxKey(dataType); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match s
|
|||
}
|
||||
|
||||
for i := 0; it.Valid() && i < count && bytes.Compare(it.RawKey(), maxKey) < 0; it.Next() {
|
||||
if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
|
||||
if k, err := db.decodeScanKey(dataType, it.Key()); err != nil {
|
||||
continue
|
||||
} else if r != nil && !r.Match(k) {
|
||||
continue
|
||||
|
@ -67,12 +67,12 @@ func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match s
|
|||
return v, nil
|
||||
}
|
||||
|
||||
func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
|
||||
return db.encodeMetaKey(dataType, nil)
|
||||
func (db *DB) encodeScanMinKey(dataType byte) ([]byte, error) {
|
||||
return db.encodeScanKey(dataType, nil)
|
||||
}
|
||||
|
||||
func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
|
||||
k, err := db.encodeMetaKey(dataType, nil)
|
||||
func (db *DB) encodeScanMaxKey(dataType byte) ([]byte, error) {
|
||||
k, err := db.encodeScanKey(dataType, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
|
|||
return k, nil
|
||||
}
|
||||
|
||||
func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
|
||||
func (db *DB) encodeScanKey(dataType byte, key []byte) ([]byte, error) {
|
||||
switch dataType {
|
||||
case KVType:
|
||||
return db.encodeKVKey(key), nil
|
||||
|
@ -98,7 +98,7 @@ func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
|
|||
return nil, errDataType
|
||||
}
|
||||
}
|
||||
func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) {
|
||||
func (db *DB) decodeScanKey(dataType byte, ek []byte) ([]byte, error) {
|
||||
if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
|
||||
return nil, errMetaKey
|
||||
}
|
||||
|
|
|
@ -174,6 +174,8 @@ func (eli *elimination) active() {
|
|||
|
||||
t.Lock()
|
||||
|
||||
t.disableLog()
|
||||
|
||||
if exp, err := Int64(dbGet(mk)); err == nil {
|
||||
// check expire again
|
||||
if exp <= now {
|
||||
|
@ -181,7 +183,7 @@ func (eli *elimination) active() {
|
|||
t.Delete(tk)
|
||||
t.Delete(mk)
|
||||
|
||||
t.Commit()
|
||||
t.expireCommit()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ type Tx struct {
|
|||
*DB
|
||||
|
||||
tx *store.Tx
|
||||
|
||||
eb *eventBatch
|
||||
}
|
||||
|
||||
func (db *DB) IsTransaction() bool {
|
||||
|
|
|
@ -43,6 +43,18 @@ func Int64(v []byte, err error) (int64, error) {
|
|||
return int64(binary.LittleEndian.Uint64(v)), nil
|
||||
}
|
||||
|
||||
func Uint64(v []byte, err error) (uint64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if v == nil || len(v) == 0 {
|
||||
return 0, nil
|
||||
} else if len(v) != 8 {
|
||||
return 0, errIntNumber
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint64(v), nil
|
||||
}
|
||||
|
||||
func PutInt64(v int64) []byte {
|
||||
var b []byte
|
||||
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
|
|
Loading…
Reference in New Issue