From c1a4753566535ba0882b197b29333439fd7936fc Mon Sep 17 00:00:00 2001
From: Mandar Harshe <mandarharshe@gmail.com>
Date: Mon, 31 Jan 2022 23:56:33 +0100
Subject: [PATCH] Add iteration bounds to provide start/stop support

---
 rocksdb/_rocksdb.pyx | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/rocksdb/_rocksdb.pyx b/rocksdb/_rocksdb.pyx
index c085051..697651b 100644
--- a/rocksdb/_rocksdb.pyx
+++ b/rocksdb/_rocksdb.pyx
@@ -113,6 +113,9 @@ cdef string_to_bytes(string ob):
 cdef Slice bytes_to_slice(ob) except *:
     return Slice(PyBytes_AsString(ob), PyBytes_Size(ob))
 
+cdef Slice* bytes_to_new_slice(ob) except *:
+    return new Slice(PyBytes_AsString(ob), PyBytes_Size(ob))
+
 cdef slice_to_bytes(Slice sl):
     return PyBytes_FromStringAndSize(sl.data(), sl.size())
 
@@ -2187,11 +2190,13 @@ cdef class DB(object):
             fill_cache=True,
             snapshot=None,
             read_tier="all",
-            total_order_seek=False):
+            total_order_seek=False,
+            iterate_lower_bound=None,
+            iterate_upper_bound=None
+    ):
 
         # TODO: Is this really effiencet ?
         return locals()
-
     cdef options.ReadOptions build_read_opts(self, dict py_opts):
         cdef options.ReadOptions opts
         opts.verify_checksums = py_opts['verify_checksums']
@@ -2209,6 +2214,22 @@ cdef class DB(object):
         else:
             raise ValueError("Invalid read_tier")
 
+        def make_bytes(iterate_bound):
+            if isinstance(iterate_bound, bytes):
+                return iterate_bound
+            elif isinstance(iterate_bound, str):
+                return str.encode(iterate_bound)
+            elif isinstance(iterate_bound, int):
+                return str.encode(str(iterate_bound))
+            else:
+                return None
+        if py_opts['iterate_lower_bound'] is not None:
+            # Calling this new without corresponding delete causes a memory leak.
+            # TODO: Figure out where the object should be destroyed without causing segfaults
+            opts.iterate_lower_bound = bytes_to_new_slice(make_bytes(py_opts['iterate_lower_bound']))
+        if py_opts['iterate_upper_bound'] is not None:
+            opts.iterate_upper_bound = bytes_to_new_slice(make_bytes(py_opts['iterate_upper_bound']))
+
         return opts
 
     property options:
-- 
GitLab