add slice for store, optimize leveldb/rocksdb get

This commit is contained in:
siddontang 2014-10-28 23:30:00 +08:00
parent e36cc553ec
commit c5107c7137
7 changed files with 139 additions and 0 deletions

View File

@ -167,6 +167,15 @@ 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

@ -12,6 +12,7 @@ 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

60
store/driver/slice.go Normal file
View File

@ -0,0 +1,60 @@
package driver
// #include <stdlib.h>
import "C"
import (
"reflect"
"unsafe"
)
type ISlice interface {
Data() []byte
Size() int
Free()
}
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.free(s.data)
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

@ -196,6 +196,14 @@ 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

@ -257,6 +257,28 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) {
return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil
}
func (db *DB) getSlice(ro *ReadOptions, key []byte) (driver.ISlice, error) {
var errStr *C.char
var vallen C.size_t
var k *C.char
if len(key) != 0 {
k = (*C.char)(unsafe.Pointer(&key[0]))
}
value := C.leveldb_get(
db.db, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr)
if errStr != nil {
return nil, saveError(errStr)
}
if value == nil {
return nil, nil
}
return driver.NewCSlice(unsafe.Pointer(value), int(vallen)), nil
}
func (db *DB) delete(wo *WriteOptions, key []byte) error {
var errStr *C.char
var k *C.char
@ -282,6 +304,10 @@ func (db *DB) Compact() error {
return nil
}
func (db *DB) GetSlice(key []byte) (driver.ISlice, error) {
return db.getSlice(db.readOpts, key)
}
func init() {
driver.Register(Store{})
}

View File

@ -311,6 +311,15 @@ 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

@ -284,6 +284,28 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) {
return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil
}
func (db *DB) getSlice(ro *ReadOptions, key []byte) (driver.ISlice, error) {
var errStr *C.char
var vallen C.size_t
var k *C.char
if len(key) != 0 {
k = (*C.char)(unsafe.Pointer(&key[0]))
}
value := C.rocksdb_get(
db.db, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr)
if errStr != nil {
return nil, saveError(errStr)
}
if value == nil {
return nil, nil
}
return driver.NewCSlice(unsafe.Pointer(value), int(vallen)), nil
}
func (db *DB) delete(wo *WriteOptions, key []byte) error {
var errStr *C.char
var k *C.char
@ -309,6 +331,10 @@ func (db *DB) Compact() error {
return nil
}
func (db *DB) GetSlice(key []byte) (driver.ISlice, error) {
return db.getSlice(db.readOpts, key)
}
func init() {
driver.Register(Store{})
}