Skip to content
Snippets Groups Projects
Commit 0dca8c37 authored by hofmockel's avatar hofmockel
Browse files

Better error reporting in python filter policy

parent 9133c81f
No related branches found
No related tags found
No related merge requests found
...@@ -191,10 +191,12 @@ cdef class PyFilterPolicy(object): ...@@ -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): ...@@ -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): ...@@ -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:
ret = (<object>ctx).create_filter( try:
[slice_to_bytes(keys[i]) for i in range(n)]) ret = (<object>ctx).create_filter(
dst.append(bytes_to_string(ret)) [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( 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:
return (<object>ctx).key_may_match( try:
slice_to_bytes(key), return (<object>ctx).key_may_match(
slice_to_bytes(filt)) 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 @cython.internal
cdef class PyBloomFilterPolicy(PyFilterPolicy): cdef class PyBloomFilterPolicy(PyFilterPolicy):
...@@ -1107,6 +1127,9 @@ cdef class DB(object): ...@@ -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
......
#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 { ...@@ -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;
}; };
} }
...@@ -2,6 +2,8 @@ from libcpp cimport bool as cpp_bool ...@@ -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": ...@@ -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": ...@@ -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+
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment