test: walk_back and walk_range (#1407)

Co-authored-by: lambdaclass-user <github@lambdaclass.com>
This commit is contained in:
Tomás
2023-02-16 17:25:21 -03:00
committed by GitHub
parent 63bbafaaa7
commit 8547fbfaed
2 changed files with 85 additions and 15 deletions

View File

@@ -100,13 +100,14 @@ impl<'tx, K: TransactionKind, T: Table> DbCursorRO<'tx, T> for Cursor<'tx, K, T>
Self: Sized,
{
let start = match range.start_bound().cloned() {
Bound::Included(key) => self.inner.set_range(key.encode().as_ref()),
Bound::Excluded(key) => {
self.inner
.set_range(key.encode().as_ref())
.map_err(|e| Error::Read(e.into()))?
.map(decoder::<T>);
self.inner.next()
Bound::Included(key) => {
if matches!(range.end_bound().cloned(), Bound::Included(end_key) | Bound::Excluded(end_key) if end_key < key) {
return Err(Error::Read(2))
}
self.inner.set_range(key.encode().as_ref())
}
Bound::Excluded(_key) => {
unreachable!("Rust doesn't allow for Bound::Excluded in starting bounds");
}
Bound::Unbounded => self.inner.first(),
}
@@ -124,13 +125,11 @@ impl<'tx, K: TransactionKind, T: Table> DbCursorRO<'tx, T> for Cursor<'tx, K, T>
Self: Sized,
{
let start = if let Some(start_key) = start_key {
self.inner
.set_range(start_key.encode().as_ref())
.map_err(|e| Error::Read(e.into()))?
.map(decoder::<T>)
decode!(self.inner.set_range(start_key.encode().as_ref()))
} else {
self.last().transpose()
};
self.last()
}
.transpose();
Ok(ReverseWalker::new(self, start))
}

View File

@@ -110,9 +110,8 @@ impl<E: EnvironmentKind> Deref for Env<E> {
/// Collection of database test utilities
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils {
use super::*;
use reth_libmdbx::WriteMap;
use super::{Env, EnvKind, EnvironmentKind, Path};
use std::sync::Arc;
/// Error during database creation
@@ -269,6 +268,39 @@ mod tests {
assert_eq!(walker.next(), Some(Ok((2, H256::zero()))));
// next() returns None after walker is done
assert_eq!(walker.next(), None);
// (∞, ∞)
let mut walker = cursor.walk_range(..).unwrap();
assert_eq!(walker.next(), Some(Ok((0, H256::zero()))));
assert_eq!(walker.next(), Some(Ok((1, H256::zero()))));
assert_eq!(walker.next(), Some(Ok((2, H256::zero()))));
assert_eq!(walker.next(), Some(Ok((3, H256::zero()))));
// next() returns None after walker is done
assert_eq!(walker.next(), None);
}
#[test]
fn db_cursor_walk_range_invalid() {
let db: Arc<Env<WriteMap>> = test_utils::create_test_db(EnvKind::RW);
// PUT (0, 0), (1, 0), (2, 0), (3, 0)
let tx = db.tx_mut().expect(ERROR_INIT_TX);
vec![0, 1, 2, 3]
.into_iter()
.try_for_each(|key| tx.put::<CanonicalHeaders>(key, H256::zero()))
.expect(ERROR_PUT);
tx.commit().expect(ERROR_COMMIT);
let tx = db.tx().expect(ERROR_INIT_TX);
let mut cursor = tx.cursor_read::<CanonicalHeaders>().unwrap();
// start bound greater than end bound
let res = cursor.walk_range(3..1);
assert!(matches!(res, Err(Error::Read(2))));
// start bound greater than end bound
let res = cursor.walk_range(15..=2);
assert!(matches!(res, Err(Error::Read(2))));
}
#[test]
@@ -331,6 +363,45 @@ mod tests {
assert_eq!(walker.next(), None);
}
#[test]
fn db_walk_back() {
let db: Arc<Env<WriteMap>> = test_utils::create_test_db(EnvKind::RW);
// PUT (0, 0), (1, 0), (3, 0)
let tx = db.tx_mut().expect(ERROR_INIT_TX);
vec![0, 1, 3]
.into_iter()
.try_for_each(|key| tx.put::<CanonicalHeaders>(key, H256::zero()))
.expect(ERROR_PUT);
tx.commit().expect(ERROR_COMMIT);
let tx = db.tx().expect(ERROR_INIT_TX);
let mut cursor = tx.cursor_read::<CanonicalHeaders>().unwrap();
let mut reverse_walker = cursor.walk_back(Some(1)).unwrap();
assert_eq!(reverse_walker.next(), Some(Ok((1, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((0, H256::zero()))));
assert_eq!(reverse_walker.next(), None);
let mut reverse_walker = cursor.walk_back(Some(2)).unwrap();
assert_eq!(reverse_walker.next(), Some(Ok((3, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((1, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((0, H256::zero()))));
assert_eq!(reverse_walker.next(), None);
let mut reverse_walker = cursor.walk_back(Some(4)).unwrap();
assert_eq!(reverse_walker.next(), Some(Ok((3, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((1, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((0, H256::zero()))));
assert_eq!(reverse_walker.next(), None);
let mut reverse_walker = cursor.walk_back(None).unwrap();
assert_eq!(reverse_walker.next(), Some(Ok((3, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((1, H256::zero()))));
assert_eq!(reverse_walker.next(), Some(Ok((0, H256::zero()))));
assert_eq!(reverse_walker.next(), None);
}
#[test]
fn db_cursor_seek_exact_or_previous_key() {
let db: Arc<Env<WriteMap>> = test_utils::create_test_db(EnvKind::RW);