Better error reporting for a python prefix extractor

This commit is contained in:
hofmockel 2014-01-26 10:45:06 +01:00
parent f16932b325
commit 41fc293cb8
3 changed files with 125 additions and 29 deletions

View file

@ -458,7 +458,7 @@ LRUCache = PyLRUCache
### Here comes the stuff for SliceTransform ### Here comes the stuff for SliceTransform
@cython.internal @cython.internal
cdef class PySliceTransform(object): cdef class PySliceTransform(object):
cdef slice_transform.SliceTransform* transfomer cdef slice_transform.SliceTransformWrapper* transfomer
cdef object ob cdef object ob
def __cinit__(self, 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)) raise TypeError("%s is not of type %s" % (ob, ISliceTransform))
self.ob = ob self.ob = ob
self.transfomer = <slice_transform.SliceTransform*>( self.transfomer = new slice_transform.SliceTransformWrapper(
new slice_transform.SliceTransformWrapper(
bytes_to_string(ob.name()), bytes_to_string(ob.name()),
<void*>ob, <void*>ob,
slice_transform_callback, slice_transform_callback,
slice_in_domain_callback, slice_in_domain_callback,
slice_in_range_callback)) slice_in_range_callback)
def __dealloc__(self): def __dealloc__(self):
if not self.transfomer == NULL: if not self.transfomer == NULL:
@ -483,9 +482,18 @@ cdef class PySliceTransform(object):
return self.ob return self.ob
cdef slice_transform.SliceTransform* get_transformer(self): cdef slice_transform.SliceTransform* get_transformer(self):
return self.transfomer return <slice_transform.SliceTransform*> 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 offset
cdef size_t size 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())) raise Exception(msg % (offset, size, src.size()))
return Slice(src.data() + offset, size) return Slice(src.data() + offset, size)
except Exception as error: except BaseException as error:
print error tb = traceback.format_exc()
# TODO: Use the rocksdb logger logger.Log(log, "Error in slice transfrom callback: %s", <bytes>tb)
return src error_msg.assign(<bytes>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: try:
return (<object>ctx).in_domain(slice_to_bytes(src)) return (<object>ctx).in_domain(slice_to_bytes(src))
except Exception as error: except BaseException as error:
print error tb = traceback.format_exc()
# TODO: Use the rocksdb logger logger.Log(log, "Error in slice transfrom callback: %s", <bytes>tb)
return False error_msg.assign(<bytes>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: try:
return (<object>ctx).in_range(slice_to_bytes(src)) return (<object>ctx).in_range(slice_to_bytes(src))
except Exception as error: except BaseException as error:
print error tb = traceback.format_exc()
# TODO: Use rocksdb logger logger.Log(log, "Error in slice transfrom callback: %s", <bytes>tb)
return False error_msg.assign(<bytes>str(error))
########################################### ###########################################
cdef class CompressionType(object): cdef class CompressionType(object):
@ -1120,6 +1138,9 @@ cdef class DB(object):
if opts.py_filter_policy is not None: if opts.py_filter_policy is not None:
opts.py_filter_policy.set_info_log(info_log) 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 = opts
self.opts.in_use = True self.opts.in_use = True

View file

@ -1,16 +1,33 @@
#include <string> #include <string>
#include "rocksdb/slice_transform.h" #include "rocksdb/slice_transform.h"
#include "rocksdb/env.h"
#include <stdexcept>
using std::string; using std::string;
using rocksdb::SliceTransform; using rocksdb::SliceTransform;
using rocksdb::Slice; using rocksdb::Slice;
using rocksdb::Logger;
namespace py_rocks { namespace py_rocks {
class SliceTransformWrapper: public SliceTransform { class SliceTransformWrapper: public SliceTransform {
public: public:
typedef Slice (*transform_func)(void*, const Slice&); typedef Slice (*transform_func)(
typedef bool (*in_domain_func)(void*, const Slice&); void*,
typedef bool (*in_range_func)(void*, const Slice&); 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( SliceTransformWrapper(
string name, string name,
@ -30,15 +47,55 @@ namespace py_rocks {
} }
Slice Transform(const Slice& src) const { 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 { 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 { 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<Logger> info_log) {
this->info_log = info_log;
} }
private: private:
@ -47,5 +104,6 @@ namespace py_rocks {
transform_func transfrom_callback; transform_func transfrom_callback;
in_domain_func in_domain_callback; in_domain_func in_domain_callback;
in_range_func in_range_callback; in_range_func in_range_callback;
std::shared_ptr<Logger> info_log;
}; };
} }

View file

@ -1,14 +1,30 @@
from slice_ cimport Slice from slice_ cimport Slice
from libcpp.string cimport string from libcpp.string cimport string
from libcpp cimport bool as cpp_bool 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 extern from "rocksdb/slice_transform.h" namespace "rocksdb":
cdef cppclass SliceTransform: cdef cppclass SliceTransform:
pass pass
ctypedef Slice (*transform_func)(void*, const Slice&) ctypedef Slice (*transform_func)(
ctypedef cpp_bool (*in_domain_func)(void*, const Slice&) void*,
ctypedef cpp_bool (*in_range_func)(void*, const Slice&) 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 extern from "cpp/slice_transform_wrapper.hpp" namespace "py_rocks":
cdef cppclass SliceTransformWrapper: cdef cppclass SliceTransformWrapper:
@ -18,3 +34,4 @@ cdef extern from "cpp/slice_transform_wrapper.hpp" namespace "py_rocks":
transform_func, transform_func,
in_domain_func, in_domain_func,
in_range_func) nogil except+ in_range_func) nogil except+
void set_info_log(shared_ptr[Logger]) nogil except+