diff --git a/rocksdb/_rocksdb.pyx b/rocksdb/_rocksdb.pyx index 0e72cb7..49b8bc7 100644 --- a/rocksdb/_rocksdb.pyx +++ b/rocksdb/_rocksdb.pyx @@ -458,7 +458,7 @@ LRUCache = PyLRUCache ### Here comes the stuff for SliceTransform @cython.internal cdef class PySliceTransform(object): - cdef slice_transform.SliceTransform* transfomer + cdef slice_transform.SliceTransformWrapper* transfomer cdef object ob def __cinit__(self, object ob): @@ -467,13 +467,12 @@ cdef class PySliceTransform(object): raise TypeError("%s is not of type %s" % (ob, ISliceTransform)) self.ob = ob - self.transfomer = ( - new slice_transform.SliceTransformWrapper( + self.transfomer = new slice_transform.SliceTransformWrapper( bytes_to_string(ob.name()), ob, slice_transform_callback, slice_in_domain_callback, - slice_in_range_callback)) + slice_in_range_callback) def __dealloc__(self): if not self.transfomer == NULL: @@ -483,9 +482,18 @@ cdef class PySliceTransform(object): return self.ob cdef slice_transform.SliceTransform* get_transformer(self): - return self.transfomer + return self.transfomer + + cdef set_info_log(self, shared_ptr[logger.Logger] info_log): + self.transfomer.set_info_log(info_log) + + +cdef Slice slice_transform_callback( + void* ctx, + logger.Logger* log, + string& error_msg, + const Slice& src) with gil: -cdef Slice slice_transform_callback(void* ctx, const Slice& src) with gil: cdef size_t offset cdef size_t size @@ -498,26 +506,36 @@ cdef Slice slice_transform_callback(void* ctx, const Slice& src) with gil: raise Exception(msg % (offset, size, src.size())) return Slice(src.data() + offset, size) - except Exception as error: - print error - # TODO: Use the rocksdb logger - return src + except BaseException as error: + tb = traceback.format_exc() + logger.Log(log, "Error in slice transfrom callback: %s", tb) + error_msg.assign(str(error)) + +cdef cpp_bool slice_in_domain_callback( + void* ctx, + logger.Logger* log, + string& error_msg, + const Slice& src) with gil: -cdef cpp_bool slice_in_domain_callback(void* ctx, const Slice& src) with gil: try: return (ctx).in_domain(slice_to_bytes(src)) - except Exception as error: - print error - # TODO: Use the rocksdb logger - return False + except BaseException as error: + tb = traceback.format_exc() + logger.Log(log, "Error in slice transfrom callback: %s", tb) + error_msg.assign(str(error)) + +cdef cpp_bool slice_in_range_callback( + void* ctx, + logger.Logger* log, + string& error_msg, + const Slice& src) with gil: -cdef cpp_bool slice_in_range_callback(void* ctx, const Slice& src) with gil: try: return (ctx).in_range(slice_to_bytes(src)) - except Exception as error: - print error - # TODO: Use rocksdb logger - return False + except BaseException as error: + tb = traceback.format_exc() + logger.Log(log, "Error in slice transfrom callback: %s", tb) + error_msg.assign(str(error)) ########################################### cdef class CompressionType(object): @@ -1120,6 +1138,9 @@ cdef class DB(object): if opts.py_filter_policy is not None: opts.py_filter_policy.set_info_log(info_log) + if opts.prefix_extractor is not None: + opts.py_prefix_extractor.set_info_log(info_log) + self.opts = opts self.opts.in_use = True diff --git a/rocksdb/cpp/slice_transform_wrapper.hpp b/rocksdb/cpp/slice_transform_wrapper.hpp index 0bc310f..4e618ee 100644 --- a/rocksdb/cpp/slice_transform_wrapper.hpp +++ b/rocksdb/cpp/slice_transform_wrapper.hpp @@ -1,16 +1,33 @@ #include #include "rocksdb/slice_transform.h" +#include "rocksdb/env.h" +#include using std::string; using rocksdb::SliceTransform; using rocksdb::Slice; +using rocksdb::Logger; namespace py_rocks { class SliceTransformWrapper: public SliceTransform { public: - typedef Slice (*transform_func)(void*, const Slice&); - typedef bool (*in_domain_func)(void*, const Slice&); - typedef bool (*in_range_func)(void*, const Slice&); + typedef Slice (*transform_func)( + void*, + Logger*, + string&, + const Slice&); + + typedef bool (*in_domain_func)( + void*, + Logger*, + string&, + const Slice&); + + typedef bool (*in_range_func)( + void*, + Logger*, + string&, + const Slice&); SliceTransformWrapper( string name, @@ -30,15 +47,55 @@ namespace py_rocks { } Slice Transform(const Slice& src) const { - return this->transfrom_callback(this->ctx, src); + string error_msg; + Slice val; + + val = this->transfrom_callback( + this->ctx, + this->info_log.get(), + error_msg, + src); + + if (error_msg.size()) { + throw std::runtime_error(error_msg.c_str()); + } + return val; } bool InDomain(const Slice& src) const { - return this->in_domain_callback(this->ctx, src); + string error_msg; + bool val; + + val = this->in_domain_callback( + this->ctx, + this->info_log.get(), + error_msg, + src); + + if (error_msg.size()) { + throw std::runtime_error(error_msg.c_str()); + } + return val; } bool InRange(const Slice& dst) const { - return this->in_range_callback(this->ctx, dst); + string error_msg; + bool val; + + val = this->in_range_callback( + this->ctx, + this->info_log.get(), + error_msg, + dst); + + if (error_msg.size()) { + throw std::runtime_error(error_msg.c_str()); + } + return val; + } + + void set_info_log(std::shared_ptr info_log) { + this->info_log = info_log; } private: @@ -47,5 +104,6 @@ namespace py_rocks { transform_func transfrom_callback; in_domain_func in_domain_callback; in_range_func in_range_callback; + std::shared_ptr info_log; }; } diff --git a/rocksdb/slice_transform.pxd b/rocksdb/slice_transform.pxd index 7a26a84..34a61f0 100644 --- a/rocksdb/slice_transform.pxd +++ b/rocksdb/slice_transform.pxd @@ -1,14 +1,30 @@ from slice_ cimport Slice from libcpp.string cimport string from libcpp cimport bool as cpp_bool +from logger cimport Logger +from std_memory cimport shared_ptr cdef extern from "rocksdb/slice_transform.h" namespace "rocksdb": cdef cppclass SliceTransform: pass -ctypedef Slice (*transform_func)(void*, const Slice&) -ctypedef cpp_bool (*in_domain_func)(void*, const Slice&) -ctypedef cpp_bool (*in_range_func)(void*, const Slice&) +ctypedef Slice (*transform_func)( + void*, + Logger*, + string&, + const Slice&) + +ctypedef cpp_bool (*in_domain_func)( + void*, + Logger*, + string&, + const Slice&) + +ctypedef cpp_bool (*in_range_func)( + void*, + Logger*, + string&, + const Slice&) cdef extern from "cpp/slice_transform_wrapper.hpp" namespace "py_rocks": cdef cppclass SliceTransformWrapper: @@ -18,3 +34,4 @@ cdef extern from "cpp/slice_transform_wrapper.hpp" namespace "py_rocks": transform_func, in_domain_func, in_range_func) nogil except+ + void set_info_log(shared_ptr[Logger]) nogil except+