update, can not run at all

This commit is contained in:
siddontang 2014-09-17 23:06:42 +08:00
parent 8b8745be92
commit 8c70bbfdbe
10 changed files with 107 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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 (

View File

@ -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() {

36
ledis/meta.go Normal file
View File

@ -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))
}

View File

@ -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

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -15,6 +15,8 @@ type Tx struct {
*DB
tx *store.Tx
eb *eventBatch
}
func (db *DB) IsTransaction() bool {

View File

@ -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))