2014-05-09 10:49:22 +04:00
|
|
|
package ledis
|
2014-05-04 15:02:55 +04:00
|
|
|
|
|
|
|
import (
|
2014-05-27 12:05:24 +04:00
|
|
|
"encoding/binary"
|
2014-05-14 12:35:49 +04:00
|
|
|
"github.com/siddontang/go-leveldb/leveldb"
|
2014-05-06 09:32:38 +04:00
|
|
|
"sync"
|
2014-05-04 15:02:55 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
type tx struct {
|
2014-05-06 09:32:38 +04:00
|
|
|
m sync.Mutex
|
|
|
|
|
2014-05-04 15:02:55 +04:00
|
|
|
wb *leveldb.WriteBatch
|
2014-05-27 12:05:24 +04:00
|
|
|
|
|
|
|
binlog *BinLog
|
|
|
|
batch [][]byte
|
|
|
|
}
|
|
|
|
|
|
|
|
func newTx(l *Ledis) *tx {
|
|
|
|
t := new(tx)
|
|
|
|
|
|
|
|
t.wb = l.ldb.NewWriteBatch()
|
|
|
|
|
|
|
|
t.batch = make([][]byte, 0, 4)
|
|
|
|
t.binlog = l.binlog
|
|
|
|
return t
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-06 09:32:38 +04:00
|
|
|
func (t *tx) Close() {
|
|
|
|
t.wb.Close()
|
|
|
|
}
|
|
|
|
|
2014-05-04 15:02:55 +04:00
|
|
|
func (t *tx) Put(key []byte, value []byte) {
|
|
|
|
t.wb.Put(key, value)
|
2014-05-27 12:05:24 +04:00
|
|
|
|
|
|
|
if t.binlog != nil {
|
2014-05-28 10:20:34 +04:00
|
|
|
buf := make([]byte, 7+len(key)+len(value))
|
2014-05-27 12:05:24 +04:00
|
|
|
buf[0] = BinLogTypeValue
|
|
|
|
pos := 1
|
2014-05-28 10:20:34 +04:00
|
|
|
binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
|
|
|
|
pos += 2
|
2014-05-27 12:05:24 +04:00
|
|
|
copy(buf[pos:], key)
|
|
|
|
pos += len(key)
|
|
|
|
binary.BigEndian.PutUint32(buf[pos:], uint32(len(value)))
|
|
|
|
pos += 4
|
|
|
|
copy(buf[pos:], value)
|
|
|
|
|
|
|
|
t.batch = append(t.batch, buf)
|
|
|
|
}
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *tx) Delete(key []byte) {
|
|
|
|
t.wb.Delete(key)
|
2014-05-27 12:05:24 +04:00
|
|
|
|
|
|
|
if t.binlog != nil {
|
2014-05-28 10:20:34 +04:00
|
|
|
buf := make([]byte, 3+len(key))
|
2014-05-27 12:05:24 +04:00
|
|
|
buf[0] = BinLogTypeDeletion
|
|
|
|
pos := 1
|
2014-05-28 10:20:34 +04:00
|
|
|
binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
|
|
|
|
pos += 2
|
2014-05-27 12:05:24 +04:00
|
|
|
copy(buf[pos:], key)
|
|
|
|
|
|
|
|
t.batch = append(t.batch, buf)
|
|
|
|
}
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|
|
|
|
|
2014-05-06 09:32:38 +04:00
|
|
|
func (t *tx) Lock() {
|
|
|
|
t.m.Lock()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *tx) Unlock() {
|
2014-05-27 12:05:24 +04:00
|
|
|
t.batch = t.batch[0:0]
|
2014-05-06 09:32:38 +04:00
|
|
|
t.wb.Rollback()
|
|
|
|
t.m.Unlock()
|
|
|
|
}
|
|
|
|
|
2014-05-04 15:02:55 +04:00
|
|
|
func (t *tx) Commit() error {
|
2014-05-27 12:05:24 +04:00
|
|
|
var err error
|
|
|
|
if t.binlog != nil {
|
|
|
|
t.binlog.Lock()
|
|
|
|
err = t.wb.Commit()
|
|
|
|
if err != nil {
|
|
|
|
t.binlog.Unlock()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = t.binlog.Log(t.batch...)
|
|
|
|
|
|
|
|
t.binlog.Unlock()
|
|
|
|
} else {
|
|
|
|
err = t.wb.Commit()
|
|
|
|
}
|
2014-05-04 15:02:55 +04:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-05-05 07:37:44 +04:00
|
|
|
func (t *tx) Rollback() {
|
|
|
|
t.wb.Rollback()
|
2014-05-04 15:02:55 +04:00
|
|
|
}
|