diff --git a/librocksdb-sys/src/lib.rs b/librocksdb-sys/src/lib.rs index 6e86a38..7cd922a 100644 --- a/librocksdb-sys/src/lib.rs +++ b/librocksdb-sys/src/lib.rs @@ -294,6 +294,8 @@ extern "C" { pub fn rocksdb_iter_seek(iterator: *mut rocksdb_iterator_t, k: *const c_char, klen: size_t); + pub fn rocksdb_iter_seek_for_prev(iterator: *mut rocksdb_iterator_t, k: *const c_char, klen: size_t); + pub fn rocksdb_iter_next(iterator: *mut rocksdb_iterator_t); pub fn rocksdb_iter_prev(iterator: *mut rocksdb_iterator_t); diff --git a/src/db.rs b/src/db.rs index 37a370f..3067928 100644 --- a/src/db.rs +++ b/src/db.rs @@ -135,6 +135,14 @@ pub struct Snapshot<'a> { /// iter.next(); /// } /// +/// // Reverse iteration from key +/// // Note, use seek_for_prev when reversing because if this key doesn't exist, +/// // this will make the iterator start from the previous key rather than the next. +/// iter.seek_for_prev(b"my key"); +/// while iter.valid() { +/// println!("Saw {:?} {:?}", iter.key(), iter.value()); +/// iter.prev(); +/// } /// ``` pub struct DBRawIterator { inner: *mut ffi::rocksdb_iterator_t, @@ -307,9 +315,6 @@ impl DBRawIterator { unsafe { ffi::rocksdb_iter_seek(self.inner, key.as_ptr() as *const c_char, key.len() as size_t); } } -/* - SeekForPrev was added in RocksDB 4.13 but not implemented in the C API until RocksDB 5.0 - /// Seeks to the specified key, or the first key that lexicographically precedes it. /// /// Like ``.seek()`` this method will attempt to seek to the specified key. @@ -336,7 +341,6 @@ impl DBRawIterator { pub fn seek_for_prev(&mut self, key: &[u8]) { unsafe { ffi::rocksdb_iter_seek_for_prev(self.inner, key.as_ptr() as *const c_char, key.len() as size_t); } } -*/ /// Seeks to the next key. /// diff --git a/tests/test_raw_iterator.rs b/tests/test_raw_iterator.rs index 7d99859..1591d90 100644 --- a/tests/test_raw_iterator.rs +++ b/tests/test_raw_iterator.rs @@ -98,7 +98,6 @@ pub fn test_seek() { let db = setup_test_db("seek"); db.put(b"k1", b"v1").unwrap(); db.put(b"k2", b"v2").unwrap(); - db.put(b"k3", b"v3").unwrap(); db.put(b"k4", b"v4").unwrap(); let mut iter = db.raw_iterator(); @@ -107,6 +106,13 @@ pub fn test_seek() { assert_eq!(iter.valid(), true); assert_eq!(iter.key(), Some(b"k2".to_vec())); assert_eq!(iter.value(), Some(b"v2".to_vec())); + + // Check it gets the next key when the key doesn't exist + iter.seek(b"k3"); + + assert_eq!(iter.valid(), true); + assert_eq!(iter.key(), Some(b"k4".to_vec())); + assert_eq!(iter.value(), Some(b"v4".to_vec())); } @@ -124,3 +130,25 @@ pub fn test_seek_to_nonexistant() { assert_eq!(iter.key(), Some(b"k3".to_vec())); assert_eq!(iter.value(), Some(b"v3".to_vec())); } + +#[test] +pub fn test_seek_for_prev() { + let db = setup_test_db("seek_for_prev"); + db.put(b"k1", b"v1").unwrap(); + db.put(b"k2", b"v2").unwrap(); + db.put(b"k4", b"v4").unwrap(); + + let mut iter = db.raw_iterator(); + iter.seek(b"k2"); + + assert_eq!(iter.valid(), true); + assert_eq!(iter.key(), Some(b"k2".to_vec())); + assert_eq!(iter.value(), Some(b"v2".to_vec())); + + // Check it gets the previous key when the key doesn't exist + iter.seek_for_prev(b"k3"); + + assert_eq!(iter.valid(), true); + assert_eq!(iter.key(), Some(b"k2".to_vec())); + assert_eq!(iter.value(), Some(b"v2".to_vec())); +}