reth_db_api/
unwind.rs

1use crate::{cursor::DbCursorRO, table::Table, transaction::DbTxMut};
2use reth_storage_errors::db::DatabaseError;
3use std::ops::RangeBounds;
4
5/// Extension trait for [`DbTxMut`] that provides unwind functionality.
6pub trait DbTxUnwindExt: DbTxMut {
7    /// Unwind table by some number key.
8    /// Returns number of rows unwound.
9    ///
10    /// Note: Key is not inclusive and specified key would stay in db.
11    #[inline]
12    fn unwind_table_by_num<T>(&self, num: u64) -> Result<usize, DatabaseError>
13    where
14        T: Table<Key = u64>,
15    {
16        self.unwind_table::<T, _>(num, |key| key)
17    }
18
19    /// Unwind the table to a provided number key.
20    /// Returns number of rows unwound.
21    ///
22    /// Note: Key is not inclusive and specified key would stay in db.
23    fn unwind_table<T, F>(&self, key: u64, mut selector: F) -> Result<usize, DatabaseError>
24    where
25        T: Table,
26        F: FnMut(T::Key) -> u64,
27    {
28        let mut cursor = self.cursor_write::<T>()?;
29        let mut reverse_walker = cursor.walk_back(None)?;
30        let mut deleted = 0;
31
32        while let Some(Ok((entry_key, _))) = reverse_walker.next() {
33            if selector(entry_key.clone()) <= key {
34                break
35            }
36            reverse_walker.delete_current()?;
37            deleted += 1;
38        }
39
40        Ok(deleted)
41    }
42
43    /// Unwind a table forward by a [`Walker`][crate::cursor::Walker] on another table.
44    ///
45    /// Note: Range is inclusive and first key in the range is removed.
46    fn unwind_table_by_walker<T1, T2>(
47        &self,
48        range: impl RangeBounds<T1::Key>,
49    ) -> Result<(), DatabaseError>
50    where
51        T1: Table,
52        T2: Table<Key = T1::Value>,
53    {
54        let mut cursor = self.cursor_write::<T1>()?;
55        let mut walker = cursor.walk_range(range)?;
56        while let Some((_, value)) = walker.next().transpose()? {
57            self.delete::<T2>(value, None)?;
58        }
59        Ok(())
60    }
61}
62
63impl<T> DbTxUnwindExt for T where T: DbTxMut {}