mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-29 00:58:11 -05:00
test: walk_back and walk_range (#1407)
Co-authored-by: lambdaclass-user <github@lambdaclass.com>
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user