forked from mirror/ledisdb
store add stat
This commit is contained in:
parent
4adf3e8996
commit
f05398cdf9
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"ImportPath": "github.com/siddontang/ledisdb",
|
||||
"GoVersion": "go1.3.2",
|
||||
"GoVersion": "go1.3.3",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
|
@ -16,27 +16,35 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/bson",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/filelock",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/hack",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/ioutil2",
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/log",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/num",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/snappy",
|
||||
"Rev": "466d5bc779ad45f5923d0f59efbc5d696bf2099c"
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/go/sync2",
|
||||
"Rev": "ada3cebe1055442f2af2840ed42cd50f64bbc6f7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/siddontang/goleveldb/leveldb",
|
||||
|
|
|
@ -25,3 +25,4 @@ go get github.com/siddontang/go/log
|
|||
go get github.com/siddontang/go/snappy
|
||||
go get github.com/siddontang/go/num
|
||||
go get github.com/siddontang/go/filelock
|
||||
go get github.com/siddontang/go/sync2
|
|
@ -10,7 +10,7 @@ import (
|
|||
type batch struct {
|
||||
l *Ledis
|
||||
|
||||
store.WriteBatch
|
||||
*store.WriteBatch
|
||||
|
||||
sync.Locker
|
||||
|
||||
|
@ -88,7 +88,7 @@ type multiBatchLocker struct {
|
|||
func (l *multiBatchLocker) Lock() {}
|
||||
func (l *multiBatchLocker) Unlock() {}
|
||||
|
||||
func (l *Ledis) newBatch(wb store.WriteBatch, locker sync.Locker, tx *Tx) *batch {
|
||||
func (l *Ledis) newBatch(wb *store.WriteBatch, locker sync.Locker, tx *Tx) *batch {
|
||||
b := new(batch)
|
||||
b.l = l
|
||||
b.WriteBatch = wb
|
||||
|
|
|
@ -26,7 +26,7 @@ type Ledis struct {
|
|||
//for replication
|
||||
r *rpl.Replication
|
||||
rc chan struct{}
|
||||
rbatch store.WriteBatch
|
||||
rbatch *store.WriteBatch
|
||||
rwg sync.WaitGroup
|
||||
rhs []NewLogEventHandler
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ type ibucket interface {
|
|||
|
||||
NewIterator() *store.Iterator
|
||||
|
||||
NewWriteBatch() store.WriteBatch
|
||||
NewWriteBatch() *store.WriteBatch
|
||||
|
||||
RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
|
||||
RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
|
||||
|
|
|
@ -190,7 +190,7 @@ func (s *snapshotStore) Create(d snapshotDumper) (*snapshot, time.Time, error) {
|
|||
|
||||
if len(s.names) > 0 {
|
||||
lastTime, _ := parseSnapshotName(s.names[len(s.names)-1])
|
||||
if !now.After(lastTime) {
|
||||
if now.Nanosecond() <= lastTime.Nanosecond() {
|
||||
return nil, time.Time{}, fmt.Errorf("create snapshot file time %s is behind %s ",
|
||||
now.Format(snapshotTimeFormat), lastTime.Format(snapshotTimeFormat))
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ func TestSnapshot(t *testing.T) {
|
|||
cfg := config.NewConfigDefault()
|
||||
cfg.Snapshot.MaxNum = 2
|
||||
cfg.Snapshot.Path = path.Join(os.TempDir(), "snapshot")
|
||||
|
||||
defer os.RemoveAll(cfg.Snapshot.Path)
|
||||
|
||||
d := new(testSnapshotDumper)
|
||||
|
|
60
store/db.go
60
store/db.go
|
@ -2,11 +2,14 @@ package store
|
|||
|
||||
import (
|
||||
"github.com/siddontang/ledisdb/store/driver"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DB struct {
|
||||
driver.IDB
|
||||
name string
|
||||
|
||||
st *Stat
|
||||
}
|
||||
|
||||
func (db *DB) String() string {
|
||||
|
@ -14,28 +17,71 @@ func (db *DB) String() string {
|
|||
}
|
||||
|
||||
func (db *DB) NewIterator() *Iterator {
|
||||
db.st.IterNum.Add(1)
|
||||
|
||||
it := new(Iterator)
|
||||
it.it = db.IDB.NewIterator()
|
||||
it.st = db.st
|
||||
|
||||
return it
|
||||
}
|
||||
|
||||
func (db *DB) NewWriteBatch() WriteBatch {
|
||||
return db.IDB.NewWriteBatch()
|
||||
func (db *DB) Get(key []byte) ([]byte, error) {
|
||||
v, err := db.IDB.Get(key)
|
||||
db.st.statGet(v, err)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (db *DB) Put(key []byte, value []byte) error {
|
||||
db.st.PutNum.Add(1)
|
||||
return db.IDB.Put(key, value)
|
||||
}
|
||||
|
||||
func (db *DB) Delete(key []byte) error {
|
||||
db.st.DeleteNum.Add(1)
|
||||
return db.IDB.Delete(key)
|
||||
}
|
||||
|
||||
func (db *DB) SyncPut(key []byte, value []byte) error {
|
||||
db.st.SyncPutNum.Add(1)
|
||||
return db.IDB.SyncPut(key, value)
|
||||
}
|
||||
|
||||
func (db *DB) SyncDelete(key []byte) error {
|
||||
db.st.SyncDeleteNum.Add(1)
|
||||
return db.IDB.SyncDelete(key)
|
||||
}
|
||||
|
||||
func (db *DB) NewWriteBatch() *WriteBatch {
|
||||
db.st.BatchNum.Add(1)
|
||||
wb := new(WriteBatch)
|
||||
wb.IWriteBatch = db.IDB.NewWriteBatch()
|
||||
wb.st = db.st
|
||||
return wb
|
||||
}
|
||||
|
||||
func (db *DB) NewSnapshot() (*Snapshot, error) {
|
||||
db.st.SnapshotNum.Add(1)
|
||||
|
||||
var err error
|
||||
s := &Snapshot{}
|
||||
if s.ISnapshot, err = db.IDB.NewSnapshot(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.st = db.st
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (db *DB) Compact() error {
|
||||
return db.IDB.Compact()
|
||||
db.st.CompactNum.Add(1)
|
||||
|
||||
t := time.Now()
|
||||
err := db.IDB.Compact()
|
||||
|
||||
db.st.CompactTotalTime.Add(time.Now().Sub(t))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
|
||||
|
@ -66,5 +112,11 @@ func (db *DB) Begin() (*Tx, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return &Tx{tx}, nil
|
||||
db.st.TxNum.Add(1)
|
||||
|
||||
return &Tx{tx, db.st}, nil
|
||||
}
|
||||
|
||||
func (db *DB) Stat() *Stat {
|
||||
return db.st
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ type Limit struct {
|
|||
|
||||
type Iterator struct {
|
||||
it driver.IIterator
|
||||
st *Stat
|
||||
}
|
||||
|
||||
// Returns a copy of key.
|
||||
|
@ -105,6 +106,7 @@ func (it *Iterator) BufValue(b []byte) []byte {
|
|||
|
||||
func (it *Iterator) Close() {
|
||||
if it.it != nil {
|
||||
it.st.IterCloseNum.Add(1)
|
||||
it.it.Close()
|
||||
it.it = nil
|
||||
}
|
||||
|
@ -115,22 +117,27 @@ func (it *Iterator) Valid() bool {
|
|||
}
|
||||
|
||||
func (it *Iterator) Next() {
|
||||
it.st.IterSeekNum.Add(1)
|
||||
it.it.Next()
|
||||
}
|
||||
|
||||
func (it *Iterator) Prev() {
|
||||
it.st.IterSeekNum.Add(1)
|
||||
it.it.Prev()
|
||||
}
|
||||
|
||||
func (it *Iterator) SeekToFirst() {
|
||||
it.st.IterSeekNum.Add(1)
|
||||
it.it.First()
|
||||
}
|
||||
|
||||
func (it *Iterator) SeekToLast() {
|
||||
it.st.IterSeekNum.Add(1)
|
||||
it.it.Last()
|
||||
}
|
||||
|
||||
func (it *Iterator) Seek(key []byte) {
|
||||
it.st.IterSeekNum.Add(1)
|
||||
it.it.Seek(key)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,26 @@ import (
|
|||
|
||||
type Snapshot struct {
|
||||
driver.ISnapshot
|
||||
st *Stat
|
||||
}
|
||||
|
||||
func (s *Snapshot) NewIterator() *Iterator {
|
||||
it := new(Iterator)
|
||||
it.it = s.ISnapshot.NewIterator()
|
||||
it.st = s.st
|
||||
|
||||
s.st.IterNum.Add(1)
|
||||
|
||||
return it
|
||||
}
|
||||
|
||||
func (s *Snapshot) Get(key []byte) ([]byte, error) {
|
||||
v, err := s.ISnapshot.Get(key)
|
||||
s.st.statGet(v, err)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (s *Snapshot) Close() {
|
||||
s.st.SnapshotCloseNum.Add(1)
|
||||
s.ISnapshot.Close()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"github.com/siddontang/go/sync2"
|
||||
)
|
||||
|
||||
type Stat struct {
|
||||
GetNum sync2.AtomicInt64
|
||||
GetMissingNum sync2.AtomicInt64
|
||||
PutNum sync2.AtomicInt64
|
||||
DeleteNum sync2.AtomicInt64
|
||||
SyncPutNum sync2.AtomicInt64
|
||||
SyncDeleteNum sync2.AtomicInt64
|
||||
IterNum sync2.AtomicInt64
|
||||
IterSeekNum sync2.AtomicInt64
|
||||
IterCloseNum sync2.AtomicInt64
|
||||
SnapshotNum sync2.AtomicInt64
|
||||
SnapshotCloseNum sync2.AtomicInt64
|
||||
BatchNum sync2.AtomicInt64
|
||||
BatchCommitNum sync2.AtomicInt64
|
||||
BatchSyncCommitNum sync2.AtomicInt64
|
||||
TxNum sync2.AtomicInt64
|
||||
TxCommitNum sync2.AtomicInt64
|
||||
TxCloseNum sync2.AtomicInt64
|
||||
CompactNum sync2.AtomicInt64
|
||||
CompactTotalTime sync2.AtomicDuration
|
||||
}
|
||||
|
||||
func (st *Stat) statGet(v []byte, err error) {
|
||||
st.GetNum.Add(1)
|
||||
if v == nil && err == nil {
|
||||
st.GetMissingNum.Add(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (st *Stat) Reset() {
|
||||
*st = Stat{}
|
||||
// st.GetNum.Set(0)
|
||||
// st.GetMissingNum.Set(0)
|
||||
// st.PutNum.Set(0)
|
||||
// st.DeleteNum.Set(0)
|
||||
// st.SyncPutNum.Set(0)
|
||||
// st.SyncDeleteNum.Set(0)
|
||||
// st.IterNum.Set(0)
|
||||
// st.IterSeekNum.Set(0)
|
||||
// st.IterCloseNum.Set(0)
|
||||
// st.SnapshotNum.Set(0)
|
||||
// st.SnapshotCloseNum.Set(0)
|
||||
// st.BatchNum.Set(0)
|
||||
// st.BatchCommitNum.Set(0)
|
||||
// st.BatchSyncCommitNum.Set(0)
|
||||
// st.TxNum.Set(0)
|
||||
// st.TxCommitNum.Set(0)
|
||||
// st.TxCloseNum.Set(0)
|
||||
// st.CompactNum.Set(0)
|
||||
// st.CompactTotalTime.Set(0)
|
||||
}
|
|
@ -40,7 +40,7 @@ func Open(cfg *config.Config) (*DB, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
db := &DB{idb, s.String()}
|
||||
db := &DB{idb, s.String(), &Stat{}}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
|
38
store/tx.go
38
store/tx.go
|
@ -6,17 +6,26 @@ import (
|
|||
|
||||
type Tx struct {
|
||||
driver.Tx
|
||||
st *Stat
|
||||
}
|
||||
|
||||
func (tx *Tx) NewIterator() *Iterator {
|
||||
it := new(Iterator)
|
||||
it.it = tx.Tx.NewIterator()
|
||||
it.st = tx.st
|
||||
|
||||
tx.st.IterNum.Add(1)
|
||||
|
||||
return it
|
||||
}
|
||||
|
||||
func (tx *Tx) NewWriteBatch() WriteBatch {
|
||||
return tx.Tx.NewWriteBatch()
|
||||
func (tx *Tx) NewWriteBatch() *WriteBatch {
|
||||
tx.st.BatchNum.Add(1)
|
||||
|
||||
wb := new(WriteBatch)
|
||||
wb.IWriteBatch = tx.Tx.NewWriteBatch()
|
||||
wb.st = tx.st
|
||||
return wb
|
||||
}
|
||||
|
||||
func (tx *Tx) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
|
||||
|
@ -40,3 +49,28 @@ func (tx *Tx) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset
|
|||
func (tx *Tx) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
|
||||
return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
|
||||
}
|
||||
|
||||
func (tx *Tx) Get(key []byte) ([]byte, error) {
|
||||
v, err := tx.Tx.Get(key)
|
||||
tx.st.statGet(v, err)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (tx *Tx) Put(key []byte, value []byte) error {
|
||||
tx.st.PutNum.Add(1)
|
||||
return tx.Tx.Put(key, value)
|
||||
}
|
||||
|
||||
func (tx *Tx) Delete(key []byte) error {
|
||||
tx.st.DeleteNum.Add(1)
|
||||
return tx.Tx.Delete(key)
|
||||
}
|
||||
|
||||
func (tx *Tx) Commit() error {
|
||||
tx.st.TxCommitNum.Add(1)
|
||||
return tx.Tx.Commit()
|
||||
}
|
||||
|
||||
func (tx *Tx) Rollback() error {
|
||||
return tx.Tx.Rollback()
|
||||
}
|
||||
|
|
|
@ -4,6 +4,41 @@ import (
|
|||
"github.com/siddontang/ledisdb/store/driver"
|
||||
)
|
||||
|
||||
type WriteBatch interface {
|
||||
type WriteBatch struct {
|
||||
driver.IWriteBatch
|
||||
st *Stat
|
||||
putNum int64
|
||||
deleteNum int64
|
||||
}
|
||||
|
||||
func (wb *WriteBatch) Put(key []byte, value []byte) {
|
||||
wb.putNum++
|
||||
wb.IWriteBatch.Put(key, value)
|
||||
}
|
||||
|
||||
func (wb *WriteBatch) Delete(key []byte) {
|
||||
wb.deleteNum++
|
||||
wb.IWriteBatch.Delete(key)
|
||||
}
|
||||
|
||||
func (wb *WriteBatch) Commit() error {
|
||||
wb.st.BatchCommitNum.Add(1)
|
||||
wb.st.PutNum.Add(wb.putNum)
|
||||
wb.st.DeleteNum.Add(wb.deleteNum)
|
||||
wb.putNum = 0
|
||||
wb.deleteNum = 0
|
||||
return wb.IWriteBatch.Commit()
|
||||
}
|
||||
|
||||
func (wb *WriteBatch) SyncCommit() error {
|
||||
wb.st.BatchSyncCommitNum.Add(1)
|
||||
wb.st.SyncPutNum.Add(wb.putNum)
|
||||
wb.st.SyncDeleteNum.Add(wb.deleteNum)
|
||||
wb.putNum = 0
|
||||
wb.deleteNum = 0
|
||||
return wb.IWriteBatch.SyncCommit()
|
||||
}
|
||||
|
||||
func (wb *WriteBatch) Rollback() error {
|
||||
return wb.IWriteBatch.Rollback()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue