|
|
|
@ -61,9 +61,9 @@ pub trait Cursor<'txn> { |
|
|
|
|
/// For databases with duplicate data items (`DatabaseFlags::DUP_SORT`), the
|
|
|
|
|
/// duplicate data items of each key will be returned before moving on to
|
|
|
|
|
/// the next key.
|
|
|
|
|
fn iter_from<K>(&mut self, key: K) -> Iter<'txn> where K: AsRef<[u8]> { |
|
|
|
|
self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE).unwrap(); |
|
|
|
|
Iter::new(self.cursor(), ffi::MDB_GET_CURRENT, ffi::MDB_NEXT) |
|
|
|
|
fn iter_from<K>(&mut self, key: K) -> Result<Iter<'txn>> where K: AsRef<[u8]> { |
|
|
|
|
try!(self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE)); |
|
|
|
|
Ok(Iter::new(self.cursor(), ffi::MDB_GET_CURRENT, ffi::MDB_NEXT)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Iterate over duplicate database items. The iterator will begin with the
|
|
|
|
@ -82,9 +82,9 @@ pub trait Cursor<'txn> { |
|
|
|
|
|
|
|
|
|
/// Iterate over duplicate items in the database starting from the given
|
|
|
|
|
/// key. Each item will be returned as an iterator of its duplicates.
|
|
|
|
|
fn iter_dup_from<K>(&mut self, key: &K) -> IterDup<'txn> where K: AsRef<[u8]> { |
|
|
|
|
self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE).unwrap(); |
|
|
|
|
IterDup::new(self.cursor(), ffi::MDB_GET_CURRENT) |
|
|
|
|
fn iter_dup_from<K>(&mut self, key: &K) -> Result<IterDup<'txn>> where K: AsRef<[u8]> { |
|
|
|
|
try!(self.get(Some(key.as_ref()), None, ffi::MDB_SET_RANGE)); |
|
|
|
|
Ok(IterDup::new(self.cursor(), ffi::MDB_GET_CURRENT)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Iterate over the duplicates of the item in the database with the given
|
|
|
|
@ -424,7 +424,8 @@ mod test { |
|
|
|
|
|
|
|
|
|
let items: Vec<(&[u8], &[u8])> = vec!((b"key1", b"val1"), |
|
|
|
|
(b"key2", b"val2"), |
|
|
|
|
(b"key3", b"val3")); |
|
|
|
|
(b"key3", b"val3"), |
|
|
|
|
(b"key5", b"val5")); |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
let mut txn = env.begin_rw_txn().unwrap(); |
|
|
|
@ -445,7 +446,12 @@ mod test { |
|
|
|
|
assert_eq!(items, cursor.iter_start().collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(1).collect::<Vec<_>>(), |
|
|
|
|
cursor.iter_from(b"key2").collect::<Vec<_>>()); |
|
|
|
|
cursor.iter_from(b"key2").unwrap().collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(3).collect::<Vec<_>>(), |
|
|
|
|
cursor.iter_from(b"key4").unwrap().collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert!(cursor.iter_from(b"key6").is_err()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
@ -462,7 +468,10 @@ mod test { |
|
|
|
|
(b"b", b"3"), |
|
|
|
|
(b"c", b"1"), |
|
|
|
|
(b"c", b"2"), |
|
|
|
|
(b"c", b"3")); |
|
|
|
|
(b"c", b"3"), |
|
|
|
|
(b"e", b"1"), |
|
|
|
|
(b"e", b"2"), |
|
|
|
|
(b"e", b"3")); |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
let mut txn = env.begin_rw_txn().unwrap(); |
|
|
|
@ -484,14 +493,18 @@ mod test { |
|
|
|
|
cursor.iter_dup_start().flat_map(|x| x).collect::<Vec<(&[u8], &[u8])>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(3).collect::<Vec<(&[u8], &[u8])>>(), |
|
|
|
|
cursor.iter_dup_from(b"b").flat_map(|x| x).collect::<Vec<_>>()); |
|
|
|
|
cursor.iter_dup_from(b"b").unwrap().flat_map(|x| x).collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(3).collect::<Vec<(&[u8], &[u8])>>(), |
|
|
|
|
cursor.iter_dup_from(b"ab").flat_map(|x| x).collect::<Vec<_>>()); |
|
|
|
|
cursor.iter_dup_from(b"ab").unwrap().flat_map(|x| x).collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(9).collect::<Vec<(&[u8], &[u8])>>(), |
|
|
|
|
cursor.iter_dup_from(b"d").unwrap().flat_map(|x| x).collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert_eq!(items.clone().into_iter().skip(3).take(3).collect::<Vec<(&[u8], &[u8])>>(), |
|
|
|
|
cursor.iter_dup_of(b"b").unwrap().collect::<Vec<_>>()); |
|
|
|
|
|
|
|
|
|
assert!(cursor.iter_dup_from(b"foo").is_err()); |
|
|
|
|
assert!(cursor.iter_dup_of(b"foo").is_err()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|