From 79b0f8d6fb207a9caceca121bb65356a95711aae Mon Sep 17 00:00:00 2001 From: twmht Date: Sun, 23 Apr 2017 19:32:41 +0800 Subject: [PATCH] add seekForPrev --- README.rst | 2 +- docs/installation.rst | 4 ++-- docs/tutorial/index.rst | 19 +++++++++++++++++ rocksdb/_rocksdb.pyx | 16 ++++++++++++++ rocksdb/iterator.pxd | 1 + rocksdb/tests/test_db.py | 46 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 3eecd93..af0b318 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,7 @@ pyrocksdb ========= Python bindings for RocksDB. -See http://pyrocksdb.readthedocs.org for a more comprehensive install and usage description. +See http://python-rocksdb.readthedocs.io/en/latest/ for a more comprehensive install and usage description. Quick Install diff --git a/docs/installation.rst b/docs/installation.rst index 91daa54..114f3ad 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -40,7 +40,7 @@ These varialbes are picked up by the compiler, linker and loader export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:`pwd` export LIBRARY_PATH=${LIBRARY_PATH}:`pwd` -Building pyrocksdb +Building python-rocksdb ------------------ .. code-block:: bash @@ -50,4 +50,4 @@ Building pyrocksdb cd pyrocks_test . bin/active pip install "Cython>=0.20" - pip install git+git://github.com/stephan-hof/pyrocksdb.git + pip install git+git://github.com/twmht/python-rocksdb.git diff --git a/docs/tutorial/index.rst b/docs/tutorial/index.rst index d7a326e..e804300 100644 --- a/docs/tutorial/index.rst +++ b/docs/tutorial/index.rst @@ -137,6 +137,25 @@ Reversed iteration :: # prints [(b'key3', b'v3'), (b'key2', b'v2'), (b'key1', b'v1')] print list(reversed(it)) +SeekForPrev (Take the example from `https://github.com/facebook/rocksdb/wiki/SeekForPrev`):: + + db.put(b'a1', b'a1_value') + db.put(b'a3', b'a3_value') + db.put(b'b1', b'b1_value') + db.put(b'b2', b'b2_value') + db.put(b'c2', b'c2_value') + db.put(b'c4', b'c4_value') + + it = db.iteritems() + it.seek(b'a1') + assertEqual(it.get(), (b'a1', b'a1_value')) + it.seek(b'a3') + assertEqual(it.get(), (b'a3', b'a3_value')) + it.seek_for_prev(b'c4') + assertEqual(it.get(), (b'c4', b'c4_value')) + it.seek_for_prev(b'c3') + assertEqual(it.get(), (b'c2', b'c2_value')) + Snapshots ========= diff --git a/rocksdb/_rocksdb.pyx b/rocksdb/_rocksdb.pyx index 4c23328..670faae 100644 --- a/rocksdb/_rocksdb.pyx +++ b/rocksdb/_rocksdb.pyx @@ -1766,6 +1766,10 @@ cdef class BaseIterator(object): check_status(self.ptr.status()) return ret + def get(self): + cdef object ret = self.get_ob() + return ret + def __reversed__(self): return ReversedIterator(self) @@ -1785,6 +1789,12 @@ cdef class BaseIterator(object): self.ptr.Seek(c_key) check_status(self.ptr.status()) + cpdef seek_for_prev(self, key): + cdef Slice c_key = bytes_to_slice(key) + with nogil: + self.ptr.SeekForPrev(c_key) + check_status(self.ptr.status()) + cdef object get_ob(self): return None @@ -1833,6 +1843,12 @@ cdef class ReversedIterator(object): def seek(self, key): self.it.seek(key) + def seek_for_prev(self, key): + self.it.seek_for_prev(key) + + def get(self): + return self.it.get() + def __iter__(self): return self diff --git a/rocksdb/iterator.pxd b/rocksdb/iterator.pxd index 5cfc24b..5cd34a8 100644 --- a/rocksdb/iterator.pxd +++ b/rocksdb/iterator.pxd @@ -10,6 +10,7 @@ cdef extern from "rocksdb/iterator.h" namespace "rocksdb": void Seek(const Slice&) nogil except+ void Next() nogil except+ void Prev() nogil except+ + void SeekForPrev(const Slice&) nogil except+ Slice key() nogil except+ Slice value() nogil except+ Status status() nogil except+ diff --git a/rocksdb/tests/test_db.py b/rocksdb/tests/test_db.py index 7eebd27..c180e4f 100644 --- a/rocksdb/tests/test_db.py +++ b/rocksdb/tests/test_db.py @@ -106,6 +106,52 @@ class TestDB(unittest.TestCase, TestHelper): self.assertEqual((True, None), self.db.key_may_exist(b'a')) self.assertEqual((True, b'1'), self.db.key_may_exist(b'a', True)) + def test_seek_for_prev(self): + self.db.put(b'a1', b'a1_value') + self.db.put(b'a3', b'a3_value') + self.db.put(b'b1', b'b1_value') + self.db.put(b'b2', b'b2_value') + self.db.put(b'c2', b'c2_value') + self.db.put(b'c4', b'c4_value') + + self.assertEqual(self.db.get(b'a1'), b'a1_value') + + it = self.db.iterkeys() + + it.seek(b'a1') + self.assertEqual(it.get(), b'a1') + it.seek(b'a3') + self.assertEqual(it.get(), b'a3') + it.seek_for_prev(b'c4') + self.assertEqual(it.get(), b'c4') + it.seek_for_prev(b'c3') + self.assertEqual(it.get(), b'c2') + + it = self.db.itervalues() + it.seek(b'a1') + self.assertEqual(it.get(), b'a1_value') + it.seek(b'a3') + self.assertEqual(it.get(), b'a3_value') + it.seek_for_prev(b'c4') + self.assertEqual(it.get(), b'c4_value') + it.seek_for_prev(b'c3') + self.assertEqual(it.get(), b'c2_value') + + it = self.db.iteritems() + it.seek(b'a1') + self.assertEqual(it.get(), (b'a1', b'a1_value')) + it.seek(b'a3') + self.assertEqual(it.get(), (b'a3', b'a3_value')) + it.seek_for_prev(b'c4') + self.assertEqual(it.get(), (b'c4', b'c4_value')) + it.seek_for_prev(b'c3') + self.assertEqual(it.get(), (b'c2', b'c2_value')) + + reverse_it = reversed(it) + it.seek_for_prev(b'c3') + self.assertEqual(it.get(), (b'c2', b'c2_value')) + + def test_iter_keys(self): for x in range(300): self.db.put(int_to_bytes(x), int_to_bytes(x))