Skip to content

Commit

Permalink
add seekForPrev
Browse files Browse the repository at this point in the history
  • Loading branch information
twmht committed Apr 23, 2017
1 parent 3fb8297 commit 79b0f8d
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
19 changes: 19 additions & 0 deletions docs/tutorial/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=========
Expand Down
16 changes: 16 additions & 0 deletions rocksdb/_rocksdb.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions rocksdb/iterator.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -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+
46 changes: 46 additions & 0 deletions rocksdb/tests/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,52 @@ def test_key_may_exists(self):
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))
Expand Down

0 comments on commit 79b0f8d

Please sign in to comment.