Better error reporting in python filter policy

This commit is contained in:
hofmockel 2014-01-26 09:47:04 +01:00
parent 9133c81f9e
commit 0dca8c379e
3 changed files with 81 additions and 12 deletions

View file

@ -191,10 +191,12 @@ cdef class PyFilterPolicy(object):
cdef const filter_policy.FilterPolicy* get_policy(self): cdef const filter_policy.FilterPolicy* get_policy(self):
return NULL return NULL
cdef set_info_log(self, shared_ptr[logger.Logger] info_log):
pass
@cython.internal @cython.internal
cdef class PyGenericFilterPolicy(PyFilterPolicy): cdef class PyGenericFilterPolicy(PyFilterPolicy):
cdef filter_policy.FilterPolicy* policy cdef filter_policy.FilterPolicyWrapper* policy
cdef object ob cdef object ob
def __cinit__(self, object ob): def __cinit__(self, object ob):
@ -203,7 +205,7 @@ cdef class PyGenericFilterPolicy(PyFilterPolicy):
raise TypeError("Cannot set filter policy: %s" % ob) raise TypeError("Cannot set filter policy: %s" % ob)
self.ob = ob self.ob = ob
self.policy = <filter_policy.FilterPolicy*> new filter_policy.FilterPolicyWrapper( self.policy = new filter_policy.FilterPolicyWrapper(
bytes_to_string(ob.name()), bytes_to_string(ob.name()),
<void*>ob, <void*>ob,
create_filter_callback, create_filter_callback,
@ -217,26 +219,44 @@ cdef class PyGenericFilterPolicy(PyFilterPolicy):
return self.ob return self.ob
cdef const filter_policy.FilterPolicy* get_policy(self): cdef const filter_policy.FilterPolicy* get_policy(self):
return self.policy return <filter_policy.FilterPolicy*> self.policy
cdef set_info_log(self, shared_ptr[logger.Logger] info_log):
self.policy.set_info_log(info_log)
cdef void create_filter_callback( cdef void create_filter_callback(
void* ctx, void* ctx,
logger.Logger* log,
string& error_msg,
const Slice* keys, const Slice* keys,
int n, int n,
string* dst) with gil: string* dst) with gil:
try:
ret = (<object>ctx).create_filter( ret = (<object>ctx).create_filter(
[slice_to_bytes(keys[i]) for i in range(n)]) [slice_to_bytes(keys[i]) for i in range(n)])
dst.append(bytes_to_string(ret)) dst.append(bytes_to_string(ret))
except BaseException as error:
tb = traceback.format_exc()
logger.Log(log, "Error in create filter callback: %s", <bytes>tb)
error_msg.assign(<bytes>str(error))
cdef cpp_bool key_may_match_callback( cdef cpp_bool key_may_match_callback(
void* ctx, void* ctx,
logger.Logger* log,
string& error_msg,
const Slice& key, const Slice& key,
const Slice& filt) with gil: const Slice& filt) with gil:
try:
return (<object>ctx).key_may_match( return (<object>ctx).key_may_match(
slice_to_bytes(key), slice_to_bytes(key),
slice_to_bytes(filt)) slice_to_bytes(filt))
except BaseException as error:
tb = traceback.format_exc()
logger.Log(log, "Error in key_mach_match callback: %s", <bytes>tb)
error_msg.assign(<bytes>str(error))
@cython.internal @cython.internal
cdef class PyBloomFilterPolicy(PyFilterPolicy): cdef class PyBloomFilterPolicy(PyFilterPolicy):
@ -1107,6 +1127,9 @@ cdef class DB(object):
if opts.py_comparator is not None: if opts.py_comparator is not None:
opts.py_comparator.set_info_log(info_log) opts.py_comparator.set_info_log(info_log)
if opts.py_filter_policy is not None:
opts.py_filter_policy.set_info_log(info_log)
self.opts = opts self.opts = opts
self.opts.in_use = True self.opts.in_use = True

View file

@ -1,20 +1,27 @@
#include "rocksdb/filter_policy.h" #include "rocksdb/filter_policy.h"
#include "rocksdb/env.h"
#include <stdexcept>
using std::string; using std::string;
using rocksdb::FilterPolicy; using rocksdb::FilterPolicy;
using rocksdb::Slice; using rocksdb::Slice;
using rocksdb::Logger;
namespace py_rocks { namespace py_rocks {
class FilterPolicyWrapper: public FilterPolicy { class FilterPolicyWrapper: public FilterPolicy {
public: public:
typedef void (*create_filter_func)( typedef void (*create_filter_func)(
void* ctx, void* ctx,
Logger*,
string&,
const Slice* keys, const Slice* keys,
int n, int n,
string* dst); string* dst);
typedef bool (*key_may_match_func)( typedef bool (*key_may_match_func)(
void* ctx, void* ctx,
Logger*,
string&,
const Slice& key, const Slice& key,
const Slice& filter); const Slice& filter);
@ -31,29 +38,52 @@ namespace py_rocks {
void void
CreateFilter(const Slice* keys, int n, std::string* dst) const { CreateFilter(const Slice* keys, int n, std::string* dst) const {
string error_msg;
this->create_filter_callback( this->create_filter_callback(
this->ctx, this->ctx,
this->info_log.get(),
error_msg,
keys, keys,
n, n,
dst); dst);
if (error_msg.size()) {
throw std::runtime_error(error_msg.c_str());
}
} }
bool bool
KeyMayMatch(const Slice& key, const Slice& filter) const { KeyMayMatch(const Slice& key, const Slice& filter) const {
return this->key_may_match_callback( string error_msg;
bool val;
val = this->key_may_match_callback(
this->ctx, this->ctx,
this->info_log.get(),
error_msg,
key, key,
filter); filter);
if (error_msg.size()) {
throw std::runtime_error(error_msg.c_str());
}
return val;
} }
const char* Name() const { const char* Name() const {
return this->name.c_str(); return this->name.c_str();
} }
void set_info_log(std::shared_ptr<Logger> info_log) {
this->info_log = info_log;
}
private: private:
string name; string name;
void* ctx; void* ctx;
create_filter_func create_filter_callback; create_filter_func create_filter_callback;
key_may_match_func key_may_match_callback; key_may_match_func key_may_match_callback;
std::shared_ptr<Logger> info_log;
}; };
} }

View file

@ -2,6 +2,8 @@ from libcpp cimport bool as cpp_bool
from libcpp.string cimport string from libcpp.string cimport string
from libc.string cimport const_char from libc.string cimport const_char
from slice_ cimport Slice from slice_ cimport Slice
from std_memory cimport shared_ptr
from logger cimport Logger
cdef extern from "rocksdb/filter_policy.h" namespace "rocksdb": cdef extern from "rocksdb/filter_policy.h" namespace "rocksdb":
cdef cppclass FilterPolicy: cdef cppclass FilterPolicy:
@ -11,8 +13,20 @@ cdef extern from "rocksdb/filter_policy.h" namespace "rocksdb":
cdef extern const FilterPolicy* NewBloomFilterPolicy(int) nogil except+ cdef extern const FilterPolicy* NewBloomFilterPolicy(int) nogil except+
ctypedef void (*create_filter_func)(void*, const Slice*, int, string*) ctypedef void (*create_filter_func)(
ctypedef cpp_bool (*key_may_match_func)(void*, const Slice&, const Slice&) void*,
Logger*,
string&,
const Slice*,
int,
string*)
ctypedef cpp_bool (*key_may_match_func)(
void*,
Logger*,
string&,
const Slice&,
const Slice&)
cdef extern from "cpp/filter_policy_wrapper.hpp" namespace "py_rocks": cdef extern from "cpp/filter_policy_wrapper.hpp" namespace "py_rocks":
cdef cppclass FilterPolicyWrapper: cdef cppclass FilterPolicyWrapper:
@ -21,3 +35,5 @@ cdef extern from "cpp/filter_policy_wrapper.hpp" namespace "py_rocks":
void*, void*,
create_filter_func, create_filter_func,
key_may_match_func) nogil except+ key_may_match_func) nogil except+
void set_info_log(shared_ptr[Logger]) nogil except+