refactor db getslice

This commit is contained in:
siddontang 2014-10-29 10:29:35 +08:00
parent 2d52dca88e
commit 8d16ac54c5
15 changed files with 122 additions and 51 deletions

View File

@ -167,15 +167,6 @@ func (db *DB) Compact() error {
return nil
}
func (db *DB) GetSlice(key []byte) (driver.ISlice, error) {
v, err := db.Get(key)
if err != nil {
return nil, err
} else {
return driver.GoSlice(v), nil
}
}
func init() {
driver.Register(Store{})
}

View File

@ -156,3 +156,20 @@ func (db *DB) needSyncCommit() bool {
}
}
func (db *DB) GetSlice(key []byte) (Slice, error) {
if d, ok := db.db.(driver.ISliceGeter); ok {
v, err := d.GetSlice(key)
db.st.statGet(v, err)
return v, err
} else {
v, err := db.Get(key)
if err != nil {
return nil, err
} else if v == nil {
return nil, nil
} else {
return driver.GoSlice(v), nil
}
}
}

View File

@ -12,7 +12,6 @@ type IDB interface {
Close() error
Get(key []byte) ([]byte, error)
GetSlice(key []byte) (ISlice, error)
Put(key []byte, value []byte) error
Delete(key []byte) error
@ -72,3 +71,7 @@ type Tx interface {
Commit() error
Rollback() error
}
type ISliceGeter interface {
GetSlice(key []byte) (ISlice, error)
}

View File

@ -196,14 +196,6 @@ func (db *DB) Compact() error {
return db.db.CompactRange(util.Range{nil, nil})
}
func (db *DB) GetSlice(key []byte) (driver.ISlice, error) {
v, err := db.Get(key)
if err != nil {
return nil, err
} else {
return driver.GoSlice(v), nil
}
}
func init() {
driver.Register(Store{})
driver.Register(MemStore{})

View File

@ -276,7 +276,7 @@ func (db *DB) getSlice(ro *ReadOptions, key []byte) (driver.ISlice, error) {
return nil, nil
}
return driver.NewCSlice(unsafe.Pointer(value), int(vallen)), nil
return NewCSlice(unsafe.Pointer(value), int(vallen)), nil
}
func (db *DB) delete(wo *WriteOptions, key []byte) error {

43
store/leveldb/slice.go Normal file
View File

@ -0,0 +1,43 @@
// +build leveldb
package leveldb
// #cgo LDFLAGS: -lleveldb
// #include "leveldb/c.h"
import "C"
import (
"reflect"
"unsafe"
)
type CSlice struct {
data unsafe.Pointer
size int
}
func NewCSlice(p unsafe.Pointer, n int) *CSlice {
return &CSlice{p, n}
}
func (s *CSlice) Data() []byte {
var value []byte
sH := (*reflect.SliceHeader)(unsafe.Pointer(&value))
sH.Cap = int(s.size)
sH.Len = int(s.size)
sH.Data = uintptr(s.data)
return value
}
func (s *CSlice) Size() int {
return int(s.size)
}
func (s *CSlice) Free() {
if s.data != nil {
C.leveldb_free(s.data)
s.data = nil
}
}

View File

@ -21,6 +21,10 @@ func (s *Snapshot) Get(key []byte) ([]byte, error) {
return s.db.get(s.readOpts, key)
}
func (s *Snapshot) GetSlice(key []byte) (driver.ISlice, error) {
return s.db.getSlice(s.readOpts, key)
}
func (s *Snapshot) NewIterator() driver.IIterator {
it := new(Iterator)
it.it = C.leveldb_create_iterator(s.db.db, s.db.iteratorOpts.Opt)

View File

@ -311,15 +311,6 @@ func (db MDB) Compact() error {
return nil
}
func (db MDB) GetSlice(key []byte) (driver.ISlice, error) {
v, err := db.Get(key)
if err != nil {
return nil, err
} else {
return driver.GoSlice(v), nil
}
}
func init() {
driver.Register(Store{})
}

View File

@ -303,7 +303,7 @@ func (db *DB) getSlice(ro *ReadOptions, key []byte) (driver.ISlice, error) {
return nil, nil
}
return driver.NewCSlice(unsafe.Pointer(value), int(vallen)), nil
return NewCSlice(unsafe.Pointer(value), int(vallen)), nil
}
func (db *DB) delete(wo *WriteOptions, key []byte) error {

View File

@ -1,5 +1,9 @@
package driver
//+build rocksdb
package rocksdb
// #cgo LDFLAGS: -lrocksdb
// #include <rocksdb/c.h>
// #include <stdlib.h>
import "C"
@ -8,12 +12,6 @@ import (
"unsafe"
)
type ISlice interface {
Data() []byte
Size() int
Free()
}
type CSlice struct {
data unsafe.Pointer
size int
@ -44,17 +42,3 @@ func (s *CSlice) Free() {
s.data = nil
}
}
type GoSlice []byte
func (s GoSlice) Data() []byte {
return []byte(s)
}
func (s GoSlice) Size() int {
return len(s)
}
func (s GoSlice) Free() {
}

View File

@ -21,6 +21,10 @@ func (s *Snapshot) Get(key []byte) ([]byte, error) {
return s.db.get(s.readOpts, key)
}
func (s *Snapshot) GetSlice(key []byte) (driver.ISlice, error) {
return s.db.getSlice(s.readOpts, key)
}
func (s *Snapshot) NewIterator() driver.IIterator {
it := new(Iterator)
it.it = C.rocksdb_create_iterator(s.db.db, s.db.iteratorOpts.Opt)

9
store/slice.go Normal file
View File

@ -0,0 +1,9 @@
package store
import (
"github.com/siddontang/ledisdb/store/driver"
)
type Slice interface {
driver.ISlice
}

View File

@ -25,6 +25,23 @@ func (s *Snapshot) Get(key []byte) ([]byte, error) {
return v, err
}
func (s *Snapshot) GetSlice(key []byte) (Slice, error) {
if d, ok := s.ISnapshot.(driver.ISliceGeter); ok {
v, err := d.GetSlice(key)
s.st.statGet(v, err)
return v, err
} else {
v, err := s.Get(key)
if err != nil {
return nil, err
} else if v == nil {
return nil, nil
} else {
return driver.GoSlice(v), nil
}
}
}
func (s *Snapshot) Close() {
s.st.SnapshotCloseNum.Add(1)
s.ISnapshot.Close()

View File

@ -23,7 +23,7 @@ type Stat struct {
CompactTotalTime sync2.AtomicDuration
}
func (st *Stat) statGet(v []byte, err error) {
func (st *Stat) statGet(v interface{}, err error) {
st.GetNum.Add(1)
if v == nil && err == nil {
st.GetMissingNum.Add(1)

View File

@ -61,6 +61,16 @@ func testSimple(db *DB, t *testing.T) {
t.Fatal("not equal")
}
if v, err := db.GetSlice(key); err != nil {
t.Fatal(err)
} else if v == nil {
t.Fatal("must not nil")
} else if !bytes.Equal(v.Data(), value) {
t.Fatal("not equal")
} else {
v.Free()
}
if err := db.Delete(key); err != nil {
t.Fatal(err)
}
@ -70,6 +80,12 @@ func testSimple(db *DB, t *testing.T) {
t.Fatal("must nil")
}
if v, err := db.GetSlice(key); err != nil {
t.Fatal(err)
} else if v != nil {
t.Fatal("must nil")
}
if err := db.Put(key, nil); err != nil {
t.Fatal(err)
}