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):
return NULL
cdef set_info_log(self, shared_ptr[logger.Logger] info_log):
pass
@cython.internal
cdef class PyGenericFilterPolicy(PyFilterPolicy):
cdef filter_policy.FilterPolicy* policy
cdef filter_policy.FilterPolicyWrapper* policy
cdef object ob
def __cinit__(self, object ob):
@ -203,7 +205,7 @@ cdef class PyGenericFilterPolicy(PyFilterPolicy):
raise TypeError("Cannot set filter policy: %s" % ob)
self.ob = ob
self.policy = <filter_policy.FilterPolicy*> new filter_policy.FilterPolicyWrapper(
self.policy = new filter_policy.FilterPolicyWrapper(
bytes_to_string(ob.name()),
<void*>ob,
create_filter_callback,
@ -217,26 +219,44 @@ cdef class PyGenericFilterPolicy(PyFilterPolicy):
return self.ob
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(
void* ctx,
logger.Logger* log,
string& error_msg,
const Slice* keys,
int n,
string* dst) with gil:
ret = (<object>ctx).create_filter(
[slice_to_bytes(keys[i]) for i in range(n)])
dst.append(bytes_to_string(ret))
try:
ret = (<object>ctx).create_filter(
[slice_to_bytes(keys[i]) for i in range(n)])
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(
void* ctx,
logger.Logger* log,
string& error_msg,
const Slice& key,
const Slice& filt) with gil:
return (<object>ctx).key_may_match(
slice_to_bytes(key),
slice_to_bytes(filt))
try:
return (<object>ctx).key_may_match(
slice_to_bytes(key),
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
cdef class PyBloomFilterPolicy(PyFilterPolicy):
@ -1107,6 +1127,9 @@ cdef class DB(object):
if opts.py_comparator is not None:
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.in_use = True

View file

@ -1,20 +1,27 @@
#include "rocksdb/filter_policy.h"
#include "rocksdb/env.h"
#include <stdexcept>
using std::string;
using rocksdb::FilterPolicy;
using rocksdb::Slice;
using rocksdb::Logger;
namespace py_rocks {
class FilterPolicyWrapper: public FilterPolicy {
public:
typedef void (*create_filter_func)(
void* ctx,
Logger*,
string&,
const Slice* keys,
int n,
string* dst);
typedef bool (*key_may_match_func)(
void* ctx,
Logger*,
string&,
const Slice& key,
const Slice& filter);
@ -31,29 +38,52 @@ namespace py_rocks {
void
CreateFilter(const Slice* keys, int n, std::string* dst) const {
string error_msg;
this->create_filter_callback(
this->ctx,
this->info_log.get(),
error_msg,
keys,
n,
dst);
if (error_msg.size()) {
throw std::runtime_error(error_msg.c_str());
}
}
bool
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->info_log.get(),
error_msg,
key,
filter);
if (error_msg.size()) {
throw std::runtime_error(error_msg.c_str());
}
return val;
}
const char* Name() const {
return this->name.c_str();
}
void set_info_log(std::shared_ptr<Logger> info_log) {
this->info_log = info_log;
}
private:
string name;
void* ctx;
create_filter_func create_filter_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 libc.string cimport const_char
from slice_ cimport Slice
from std_memory cimport shared_ptr
from logger cimport Logger
cdef extern from "rocksdb/filter_policy.h" namespace "rocksdb":
cdef cppclass FilterPolicy:
@ -11,8 +13,20 @@ cdef extern from "rocksdb/filter_policy.h" namespace "rocksdb":
cdef extern const FilterPolicy* NewBloomFilterPolicy(int) nogil except+
ctypedef void (*create_filter_func)(void*, const Slice*, int, string*)
ctypedef cpp_bool (*key_may_match_func)(void*, const Slice&, const Slice&)
ctypedef void (*create_filter_func)(
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 cppclass FilterPolicyWrapper:
@ -21,3 +35,5 @@ cdef extern from "cpp/filter_policy_wrapper.hpp" namespace "py_rocks":
void*,
create_filter_func,
key_may_match_func) nogil except+
void set_info_log(shared_ptr[Logger]) nogil except+