forked from mirror/ledisdb
refactor db getslice
This commit is contained in:
parent
2d52dca88e
commit
8d16ac54c5
|
@ -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{})
|
||||
}
|
||||
|
|
17
store/db.go
17
store/db.go
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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{})
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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{})
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"github.com/siddontang/ledisdb/store/driver"
|
||||
)
|
||||
|
||||
type Slice interface {
|
||||
driver.ISlice
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue