diff --git a/store/db.go b/store/db.go index 76c63e3..ca57326 100644 --- a/store/db.go +++ b/store/db.go @@ -19,6 +19,16 @@ func (db *DB) NewWriteBatch() WriteBatch { return db.IDB.NewWriteBatch() } +func (db *DB) NewSnapshot() (*Snapshot, error) { + var err error + s := &Snapshot{} + if s.ISnapshot, err = db.IDB.NewSnapshot(); err != nil { + return nil, err + } + + return s, nil +} + func (db *DB) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator { return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1}) } diff --git a/store/hyperleveldb/db.go b/store/hyperleveldb/db.go index e8ec944..6d0e176 100644 --- a/store/hyperleveldb/db.go +++ b/store/hyperleveldb/db.go @@ -234,10 +234,8 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) { k = (*C.char)(unsafe.Pointer(&key[0])) } - var value *C.char - - c := C.hyperleveldb_get_ext( - db.db, ro.Opt, k, C.size_t(len(key)), &value, &vallen, &errStr) + value := C.leveldb_get( + db.db, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr) if errStr != nil { return nil, saveError(errStr) @@ -247,7 +245,7 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) { return nil, nil } - defer C.hyperleveldb_get_free_ext(unsafe.Pointer(c)) + defer C.leveldb_free(unsafe.Pointer(value)) return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil } diff --git a/store/hyperleveldb/hyperleveldb_ext.cc b/store/hyperleveldb/hyperleveldb_ext.cc index dab687c..f775ee9 100644 --- a/store/hyperleveldb/hyperleveldb_ext.cc +++ b/store/hyperleveldb/hyperleveldb_ext.cc @@ -3,60 +3,60 @@ #include "hyperleveldb_ext.h" #include -#include +//#include -#include "hyperleveldb/db.h" +//#include "hyperleveldb/db.h" -using namespace leveldb; +//using namespace leveldb; extern "C" { -static bool SaveError(char** errptr, const Status& s) { - assert(errptr != NULL); - if (s.ok()) { - return false; - } else if (*errptr == NULL) { - *errptr = strdup(s.ToString().c_str()); - } else { - free(*errptr); - *errptr = strdup(s.ToString().c_str()); - } - return true; -} +// static bool SaveError(char** errptr, const Status& s) { +// assert(errptr != NULL); +// if (s.ok()) { +// return false; +// } else if (*errptr == NULL) { +// *errptr = strdup(s.ToString().c_str()); +// } else { +// free(*errptr); +// *errptr = strdup(s.ToString().c_str()); +// } +// return true; +// } -void* hyperleveldb_get_ext( - leveldb_t* db, - const leveldb_readoptions_t* options, - const char* key, size_t keylen, - char** valptr, - size_t* vallen, - char** errptr) { +// void* hyperleveldb_get_ext( +// leveldb_t* db, +// const leveldb_readoptions_t* options, +// const char* key, size_t keylen, +// char** valptr, +// size_t* vallen, +// char** errptr) { - std::string *tmp = new(std::string); +// std::string *tmp = new(std::string); - //very tricky, maybe changed with c++ leveldb upgrade - Status s = (*(DB**)db)->Get(*(ReadOptions*)options, Slice(key, keylen), tmp); +// //very tricky, maybe changed with c++ leveldb upgrade +// Status s = (*(DB**)db)->Get(*(ReadOptions*)options, Slice(key, keylen), tmp); - if (s.ok()) { - *valptr = (char*)tmp->data(); - *vallen = tmp->size(); - } else { - delete(tmp); - tmp = NULL; - *valptr = NULL; - *vallen = 0; - if (!s.IsNotFound()) { - SaveError(errptr, s); - } - } - return tmp; -} +// if (s.ok()) { +// *valptr = (char*)tmp->data(); +// *vallen = tmp->size(); +// } else { +// delete(tmp); +// tmp = NULL; +// *valptr = NULL; +// *vallen = 0; +// if (!s.IsNotFound()) { +// SaveError(errptr, s); +// } +// } +// return tmp; +// } -void hyperleveldb_get_free_ext(void* context) { - std::string* s = (std::string*)context; +// void hyperleveldb_get_free_ext(void* context) { +// std::string* s = (std::string*)context; - delete(s); -} +// delete(s); +// } unsigned char hyperleveldb_iter_seek_to_first_ext(leveldb_iterator_t* iter) { diff --git a/store/hyperleveldb/hyperleveldb_ext.h b/store/hyperleveldb/hyperleveldb_ext.h index 940a090..9182768 100644 --- a/store/hyperleveldb/hyperleveldb_ext.h +++ b/store/hyperleveldb/hyperleveldb_ext.h @@ -10,19 +10,19 @@ extern "C" { #include "hyperleveldb/c.h" -/* Returns NULL if not found. Otherwise stores the value in **valptr. - Stores the length of the value in *vallen. - Returns a context must be later to free*/ -extern void* hyperleveldb_get_ext( - leveldb_t* db, - const leveldb_readoptions_t* options, - const char* key, size_t keylen, - char** valptr, - size_t* vallen, - char** errptr); +// /* Returns NULL if not found. Otherwise stores the value in **valptr. +// Stores the length of the value in *vallen. +// Returns a context must be later to free*/ +// extern void* hyperleveldb_get_ext( +// leveldb_t* db, +// const leveldb_readoptions_t* options, +// const char* key, size_t keylen, +// char** valptr, +// size_t* vallen, +// char** errptr); -// Free context returns by hyperleveldb_get_ext -extern void hyperleveldb_get_free_ext(void* context); +// // Free context returns by hyperleveldb_get_ext +// extern void hyperleveldb_get_free_ext(void* context); // Below iterator functions like leveldb iterator but returns valid status for iterator diff --git a/store/leveldb/db.go b/store/leveldb/db.go index 0a40953..43ee0c2 100644 --- a/store/leveldb/db.go +++ b/store/leveldb/db.go @@ -234,10 +234,8 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) { k = (*C.char)(unsafe.Pointer(&key[0])) } - var value *C.char - - c := C.leveldb_get_ext( - db.db, ro.Opt, k, C.size_t(len(key)), &value, &vallen, &errStr) + value := C.leveldb_get( + db.db, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr) if errStr != nil { return nil, saveError(errStr) @@ -247,7 +245,7 @@ func (db *DB) get(ro *ReadOptions, key []byte) ([]byte, error) { return nil, nil } - defer C.leveldb_get_free_ext(unsafe.Pointer(c)) + defer C.leveldb_free(unsafe.Pointer(value)) return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil } diff --git a/store/leveldb/leveldb_ext.cc b/store/leveldb/leveldb_ext.cc index 96d6541..a362ab5 100644 --- a/store/leveldb/leveldb_ext.cc +++ b/store/leveldb/leveldb_ext.cc @@ -3,60 +3,60 @@ #include "leveldb_ext.h" #include -#include +//#include -#include "leveldb/db.h" +//#include "leveldb/db.h" -using namespace leveldb; +//using namespace leveldb; extern "C" { -static bool SaveError(char** errptr, const Status& s) { - assert(errptr != NULL); - if (s.ok()) { - return false; - } else if (*errptr == NULL) { - *errptr = strdup(s.ToString().c_str()); - } else { - free(*errptr); - *errptr = strdup(s.ToString().c_str()); - } - return true; -} +// static bool SaveError(char** errptr, const Status& s) { +// assert(errptr != NULL); +// if (s.ok()) { +// return false; +// } else if (*errptr == NULL) { +// *errptr = strdup(s.ToString().c_str()); +// } else { +// free(*errptr); +// *errptr = strdup(s.ToString().c_str()); +// } +// return true; +// } -void* leveldb_get_ext( - leveldb_t* db, - const leveldb_readoptions_t* options, - const char* key, size_t keylen, - char** valptr, - size_t* vallen, - char** errptr) { +// void* leveldb_get_ext( +// leveldb_t* db, +// const leveldb_readoptions_t* options, +// const char* key, size_t keylen, +// char** valptr, +// size_t* vallen, +// char** errptr) { - std::string *tmp = new(std::string); +// std::string *tmp = new(std::string); - //very tricky, maybe changed with c++ leveldb upgrade - Status s = (*(DB**)db)->Get(*(ReadOptions*)options, Slice(key, keylen), tmp); +// //very tricky, maybe changed with c++ leveldb upgrade +// Status s = (*(DB**)db)->Get(*(ReadOptions*)options, Slice(key, keylen), tmp); - if (s.ok()) { - *valptr = (char*)tmp->data(); - *vallen = tmp->size(); - } else { - delete(tmp); - tmp = NULL; - *valptr = NULL; - *vallen = 0; - if (!s.IsNotFound()) { - SaveError(errptr, s); - } - } - return tmp; -} +// if (s.ok()) { +// *valptr = (char*)tmp->data(); +// *vallen = tmp->size(); +// } else { +// delete(tmp); +// tmp = NULL; +// *valptr = NULL; +// *vallen = 0; +// if (!s.IsNotFound()) { +// SaveError(errptr, s); +// } +// } +// return tmp; +// } -void leveldb_get_free_ext(void* context) { - std::string* s = (std::string*)context; +// void leveldb_get_free_ext(void* context) { +// std::string* s = (std::string*)context; - delete(s); -} +// delete(s); +// } unsigned char leveldb_iter_seek_to_first_ext(leveldb_iterator_t* iter) { diff --git a/store/leveldb/leveldb_ext.h b/store/leveldb/leveldb_ext.h index 8222ae3..1c5f986 100644 --- a/store/leveldb/leveldb_ext.h +++ b/store/leveldb/leveldb_ext.h @@ -10,19 +10,19 @@ extern "C" { #include "leveldb/c.h" -/* Returns NULL if not found. Otherwise stores the value in **valptr. - Stores the length of the value in *vallen. - Returns a context must be later to free*/ -extern void* leveldb_get_ext( - leveldb_t* db, - const leveldb_readoptions_t* options, - const char* key, size_t keylen, - char** valptr, - size_t* vallen, - char** errptr); +// /* Returns NULL if not found. Otherwise stores the value in **valptr. +// Stores the length of the value in *vallen. +// Returns a context must be later to free*/ +// extern void* leveldb_get_ext( +// leveldb_t* db, +// const leveldb_readoptions_t* options, +// const char* key, size_t keylen, +// char** valptr, +// size_t* vallen, +// char** errptr); -// Free context returns by leveldb_get_ext -extern void leveldb_get_free_ext(void* context); +// // Free context returns by leveldb_get_ext +// extern void leveldb_get_free_ext(void* context); // Below iterator functions like leveldb iterator but returns valid status for iterator diff --git a/store/snapshot.go b/store/snapshot.go new file mode 100644 index 0000000..3f7538a --- /dev/null +++ b/store/snapshot.go @@ -0,0 +1,16 @@ +package store + +import ( + "github.com/siddontang/ledisdb/store/driver" +) + +type Snapshot struct { + driver.ISnapshot +} + +func (s *Snapshot) NewIterator() *Iterator { + it := new(Iterator) + it.it = s.ISnapshot.NewIterator() + + return it +}