2014-09-02 13:55:12 +04:00
|
|
|
package ledis
|
|
|
|
|
|
|
|
import (
|
2014-09-22 13:50:51 +04:00
|
|
|
"github.com/siddontang/go-log/log"
|
|
|
|
"github.com/siddontang/ledisdb/rpl"
|
2014-09-02 13:55:12 +04:00
|
|
|
"github.com/siddontang/ledisdb/store"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type batch struct {
|
|
|
|
l *Ledis
|
|
|
|
|
|
|
|
store.WriteBatch
|
|
|
|
|
|
|
|
sync.Locker
|
|
|
|
|
2014-09-17 13:54:04 +04:00
|
|
|
eb *eventBatch
|
2014-09-02 13:55:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *batch) Commit() error {
|
2014-09-22 13:50:51 +04:00
|
|
|
if b.l.IsReadOnly() {
|
|
|
|
return ErrWriteInROnly
|
2014-09-17 19:06:42 +04:00
|
|
|
}
|
|
|
|
|
2014-09-02 13:55:12 +04:00
|
|
|
b.l.commitLock.Lock()
|
|
|
|
defer b.l.commitLock.Unlock()
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
var err error
|
|
|
|
if b.l.r != nil {
|
|
|
|
var l *rpl.Log
|
|
|
|
if l, err = b.l.r.Log(b.eb.Bytes()); err != nil {
|
|
|
|
log.Fatal("write wal error %s", err.Error())
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-09-23 13:28:09 +04:00
|
|
|
b.l.propagate(l)
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
if err = b.WriteBatch.Commit(); err != nil {
|
|
|
|
log.Fatal("commit error %s", err.Error())
|
|
|
|
return err
|
|
|
|
}
|
2014-09-02 13:55:12 +04:00
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
if err = b.l.r.UpdateCommitID(l.ID); err != nil {
|
|
|
|
log.Fatal("update commit id error %s", err.Error())
|
|
|
|
return err
|
2014-09-02 13:55:12 +04:00
|
|
|
}
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
return nil
|
|
|
|
} else {
|
|
|
|
return b.WriteBatch.Commit()
|
2014-09-17 19:06:42 +04:00
|
|
|
}
|
2014-09-02 13:55:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *batch) Lock() {
|
|
|
|
b.Locker.Lock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *batch) Unlock() {
|
2014-09-17 19:06:42 +04:00
|
|
|
b.eb.Reset()
|
2014-09-22 13:50:51 +04:00
|
|
|
|
2014-09-02 13:55:12 +04:00
|
|
|
b.WriteBatch.Rollback()
|
|
|
|
b.Locker.Unlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *batch) Put(key []byte, value []byte) {
|
2014-09-22 13:50:51 +04:00
|
|
|
if b.l.r != nil {
|
2014-09-17 19:06:42 +04:00
|
|
|
b.eb.Put(key, value)
|
2014-09-02 13:55:12 +04:00
|
|
|
}
|
2014-09-22 13:50:51 +04:00
|
|
|
|
2014-09-02 13:55:12 +04:00
|
|
|
b.WriteBatch.Put(key, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *batch) Delete(key []byte) {
|
2014-09-22 13:50:51 +04:00
|
|
|
if b.l.r != nil {
|
|
|
|
b.Delete(key)
|
2014-09-02 13:55:12 +04:00
|
|
|
}
|
2014-09-17 13:54:04 +04:00
|
|
|
|
2014-09-02 13:55:12 +04:00
|
|
|
b.WriteBatch.Delete(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
type dbBatchLocker struct {
|
|
|
|
l *sync.Mutex
|
|
|
|
wrLock *sync.RWMutex
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *dbBatchLocker) Lock() {
|
|
|
|
l.wrLock.RLock()
|
|
|
|
l.l.Lock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *dbBatchLocker) Unlock() {
|
|
|
|
l.l.Unlock()
|
|
|
|
l.wrLock.RUnlock()
|
|
|
|
}
|
|
|
|
|
|
|
|
type multiBatchLocker struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *multiBatchLocker) Lock() {}
|
|
|
|
func (l *multiBatchLocker) Unlock() {}
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
func (l *Ledis) newBatch(wb store.WriteBatch, locker sync.Locker) *batch {
|
2014-09-02 13:55:12 +04:00
|
|
|
b := new(batch)
|
|
|
|
b.l = l
|
|
|
|
b.WriteBatch = wb
|
|
|
|
|
|
|
|
b.Locker = locker
|
|
|
|
|
2014-09-22 13:50:51 +04:00
|
|
|
b.eb = new(eventBatch)
|
2014-09-17 13:54:04 +04:00
|
|
|
|
2014-09-02 13:55:12 +04:00
|
|
|
return b
|
|
|
|
}
|