diff --git a/tools/build_rocksdb_ext.sh b/tools/build_rocksdb_ext.sh new file mode 100644 index 0000000..1701cac --- /dev/null +++ b/tools/build_rocksdb_ext.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +ROCKSDB_DIR=/usr/local/rocksdb + +if test -z "$TARGET_OS"; then + TARGET_OS=`uname -s` +fi + +PLATFORM_SHARED_EXT="so" +PLATFORM_SHARED_LDFLAGS="-shared -Wl,-soname -Wl," +PLATFORM_SHARED_CFLAGS="-fPIC" + +if [ "$TARGET_OS" = "Darwin" ]; then + PLATFORM_SHARED_EXT=dylib + PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name " +fi + +SONAME=librocksdb_ext.$PLATFORM_SHARED_EXT + +g++ $PLATFORM_SHARED_LDFLAGS$SONAME $PLATFORM_SHARED_CFLAGS -std=c++0x -L$ROCKSDB_DIR/lib -lrocksdb -I/$ROCKSDB_DIR/include rocksdb_ext.cc -o $SONAME \ No newline at end of file diff --git a/tools/rocksdb_ext.cc b/tools/rocksdb_ext.cc new file mode 100644 index 0000000..95713a6 --- /dev/null +++ b/tools/rocksdb_ext.cc @@ -0,0 +1,57 @@ +#include +#include + +#include + +using namespace rocksdb; + +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; +} + +void* rocksdb_get_ext( + rocksdb_t* db, + const rocksdb_readoptions_t* options, + const char* key, size_t keylen, + char** valptr, + size_t* vallen, + char** errptr) { + + std::string *tmp = new(std::string); + + //very tricky, maybe changed with c++ rocksdb 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; +} + +void rocksdb_get_free_ext(void* context) { + std::string* s = (std::string*)context; + + delete(s); +} + +} \ No newline at end of file