From 6f452968bc8dde9736754930097b3bcef3d50bb3 Mon Sep 17 00:00:00 2001 From: hofmockel <dreagonfly@gmx.de> Date: Sun, 19 Jan 2014 12:53:57 +0100 Subject: [PATCH] PySliceTransfrom to bridge python and c++ --- rocksdb/_rocksdb.pyx | 60 +++++++++++++++++++++++++++++++++++++ rocksdb/interfaces.py | 19 ++++++++++++ rocksdb/slice_transform.pxd | 20 +++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 rocksdb/slice_transform.pxd diff --git a/rocksdb/_rocksdb.pyx b/rocksdb/_rocksdb.pyx index 0f37b79..04e7fd3 100644 --- a/rocksdb/_rocksdb.pyx +++ b/rocksdb/_rocksdb.pyx @@ -15,6 +15,7 @@ cimport options cimport merge_operator cimport filter_policy cimport comparator +cimport slice_transform cimport cache cimport logger cimport snapshot @@ -29,6 +30,7 @@ from interfaces import MergeOperator as IMergeOperator from interfaces import AssociativeMergeOperator as IAssociativeMergeOperator from interfaces import FilterPolicy as IFilterPolicy from interfaces import Comparator as IComparator +from interfaces import SliceTransform as ISliceTransform import traceback import errors @@ -426,7 +428,65 @@ cdef class PyLRUCache(PyCache): LRUCache = PyLRUCache ############################### +### Here comes the stuff for SliceTransform +@cython.internal +cdef class PySliceTransform(object): + cdef slice_transform.SliceTransform* transfomer + cdef object ob + + def __cinit__(self, object ob): + if not isinstance(ob, ISliceTransform): + raise TypeError("%s is not of type %s" % (ob, ISliceTransform)) + + self.ob = ob + self.transfomer = <slice_transform.SliceTransform*>( + new slice_transform.SliceTransformWrapper( + bytes_to_string(ob.name()), + <void*>ob, + slice_transform_callback, + slice_in_domain_callback, + slice_in_range_callback)) + + def __dealloc__(self): + del self.transfomer + + cdef object get_ob(self): + return self.ob + + cdef slice_transform.SliceTransform* get_transformer(self): + return self.transfomer + +cdef Slice slice_transform_callback(void* ctx, const Slice& src) with gil: + cdef size_t offset + cdef size_t size + + try: + ret = (<object>ctx).transform(slice_to_bytes(src)) + offset = ret[0] + size = ret[1] + return Slice(src.data() + offset, size) + except Exception as error: + print error + # TODO: Use the rocksdb logger + return src + +cdef cpp_bool slice_in_domain_callback(void* ctx, const Slice& src) with gil: + try: + return (<object>ctx).in_domain(slice_to_bytes(src)) + except Exception as error: + print error + # TODO: Use the rocksdb logger + return False + +cdef cpp_bool slice_in_range_callback(void* ctx, const Slice& src) with gil: + try: + return (<object>ctx).in_range(slice_to_bytes(src)) + except Exception as error: + print error + # TODO: Use rocksdb logger + return False +########################################### cdef class CompressionType(object): no_compression = u'no_compression' snappy_compression = u'snappy_compression' diff --git a/rocksdb/interfaces.py b/rocksdb/interfaces.py index 19bf658..d9812a7 100644 --- a/rocksdb/interfaces.py +++ b/rocksdb/interfaces.py @@ -56,3 +56,22 @@ class FilterPolicy: @abstractmethod def key_may_match(self, key, filter_): pass + +class SliceTransform: + __metaclass__ = ABCMeta + + @abstractmethod + def name(self): + pass + + @abstractmethod + def transform(self, src): + pass + + @abstractmethod + def in_domain(self, src): + pass + + @abstractmethod + def in_range(self, dst): + pass diff --git a/rocksdb/slice_transform.pxd b/rocksdb/slice_transform.pxd new file mode 100644 index 0000000..7a26a84 --- /dev/null +++ b/rocksdb/slice_transform.pxd @@ -0,0 +1,20 @@ +from slice_ cimport Slice +from libcpp.string cimport string +from libcpp cimport bool as cpp_bool + +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&) + +cdef extern from "cpp/slice_transform_wrapper.hpp" namespace "py_rocks": + cdef cppclass SliceTransformWrapper: + SliceTransformWrapper( + string name, + void*, + transform_func, + in_domain_func, + in_range_func) nogil except+ -- GitLab