2014-05-20 04:41:24 +04:00
|
|
|
package ledis
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"github.com/siddontang/go-leveldb/leveldb"
|
2014-06-03 05:51:29 +04:00
|
|
|
"github.com/siddontang/ledisdb/replication"
|
2014-05-29 11:07:14 +04:00
|
|
|
"sync"
|
2014-05-20 04:41:24 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
DataDB leveldb.Config `json:"data_db"`
|
2014-05-27 12:05:24 +04:00
|
|
|
|
2014-06-05 11:59:10 +04:00
|
|
|
BinLog replication.BinLogConfig `json:"binlog"`
|
|
|
|
RelayLog replication.RelayLogConfig `json:"relaylog"`
|
2014-05-20 04:41:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
type DB struct {
|
2014-06-05 11:59:10 +04:00
|
|
|
l *Ledis
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
db *leveldb.DB
|
|
|
|
|
|
|
|
index uint8
|
|
|
|
|
|
|
|
kvTx *tx
|
|
|
|
listTx *tx
|
|
|
|
hashTx *tx
|
|
|
|
zsetTx *tx
|
|
|
|
}
|
|
|
|
|
|
|
|
type Ledis struct {
|
2014-05-29 11:07:14 +04:00
|
|
|
sync.Mutex
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
cfg *Config
|
|
|
|
|
|
|
|
ldb *leveldb.DB
|
|
|
|
dbs [MaxDBNumber]*DB
|
2014-05-27 12:05:24 +04:00
|
|
|
|
2014-06-05 11:59:10 +04:00
|
|
|
binlog *replication.Log
|
|
|
|
relaylog *replication.Log
|
|
|
|
|
|
|
|
quit chan struct{}
|
2014-05-20 04:41:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func Open(configJson json.RawMessage) (*Ledis, error) {
|
|
|
|
var cfg Config
|
|
|
|
|
|
|
|
if err := json.Unmarshal(configJson, &cfg); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return OpenWithConfig(&cfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func OpenWithConfig(cfg *Config) (*Ledis, error) {
|
|
|
|
ldb, err := leveldb.OpenWithConfig(&cfg.DataDB)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
l := new(Ledis)
|
2014-06-05 11:59:10 +04:00
|
|
|
|
|
|
|
l.quit = make(chan struct{})
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
l.ldb = ldb
|
|
|
|
|
2014-05-27 12:05:24 +04:00
|
|
|
if len(cfg.BinLog.Path) > 0 {
|
2014-06-03 05:51:29 +04:00
|
|
|
l.binlog, err = replication.NewBinLogWithConfig(&cfg.BinLog)
|
2014-05-27 12:05:24 +04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
l.binlog = nil
|
|
|
|
}
|
|
|
|
|
2014-06-05 11:59:10 +04:00
|
|
|
if len(cfg.RelayLog.Path) > 0 {
|
|
|
|
l.relaylog, err = replication.NewRelayLogWithConfig(&cfg.RelayLog)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
l.relaylog = nil
|
|
|
|
}
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
for i := uint8(0); i < MaxDBNumber; i++ {
|
|
|
|
l.dbs[i] = newDB(l, i)
|
|
|
|
}
|
|
|
|
|
|
|
|
return l, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func newDB(l *Ledis, index uint8) *DB {
|
|
|
|
d := new(DB)
|
|
|
|
|
2014-06-05 11:59:10 +04:00
|
|
|
d.l = l
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
d.db = l.ldb
|
|
|
|
|
|
|
|
d.index = index
|
|
|
|
|
2014-05-27 12:05:24 +04:00
|
|
|
d.kvTx = newTx(l)
|
|
|
|
d.listTx = newTx(l)
|
|
|
|
d.hashTx = newTx(l)
|
|
|
|
d.zsetTx = newTx(l)
|
2014-05-20 04:41:24 +04:00
|
|
|
|
2014-06-03 11:40:10 +04:00
|
|
|
d.activeExpireCycle()
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Ledis) Close() {
|
2014-06-05 11:59:10 +04:00
|
|
|
close(l.quit)
|
|
|
|
|
2014-05-20 04:41:24 +04:00
|
|
|
l.ldb.Close()
|
2014-06-05 11:59:10 +04:00
|
|
|
|
|
|
|
if l.binlog != nil {
|
|
|
|
l.binlog.Close()
|
|
|
|
l.binlog = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if l.relaylog != nil {
|
|
|
|
l.relaylog.Close()
|
|
|
|
l.relaylog = nil
|
|
|
|
}
|
2014-05-20 04:41:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Ledis) Select(index int) (*DB, error) {
|
|
|
|
if index < 0 || index >= int(MaxDBNumber) {
|
|
|
|
return nil, fmt.Errorf("invalid db index %d", index)
|
|
|
|
}
|
|
|
|
|
|
|
|
return l.dbs[index], nil
|
|
|
|
}
|