add iter-from for bags-list (#11104)

* add iter-from for bags-list

* Fix

* Apply suggestions from code review

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Kian Paimani
2022-03-31 15:16:34 +01:00
committed by GitHub
parent 6ec4ee1647
commit c2d3d488b8
5 changed files with 79 additions and 2 deletions
+29
View File
@@ -42,6 +42,8 @@ use sp_std::{
pub enum ListError {
/// A duplicate id has been detected.
Duplicate,
/// Given node id was not found.
NodeNotFound,
}
#[cfg(test)]
@@ -244,6 +246,33 @@ impl<T: Config<I>, I: 'static> List<T, I> {
iter.filter_map(Bag::get).flat_map(|bag| bag.iter())
}
/// Same as `iter`, but we start from a specific node.
///
/// All items after this node are returned, excluding `start` itself.
pub(crate) fn iter_from(
start: &T::AccountId,
) -> Result<impl Iterator<Item = Node<T, I>>, ListError> {
// We chain two iterators:
// 1. from the given `start` till the end of the bag
// 2. all the bags that come after `start`'s bag.
let start_node = Node::<T, I>::get(start).ok_or(ListError::NodeNotFound)?;
let start_node_upper = start_node.bag_upper;
let start_bag = sp_std::iter::successors(start_node.next(), |prev| prev.next());
let thresholds = T::BagThresholds::get();
let idx = thresholds.partition_point(|&threshold| start_node_upper > threshold);
let leftover_bags = thresholds
.into_iter()
.take(idx)
.copied()
.rev()
.filter_map(Bag::get)
.flat_map(|bag| bag.iter());
Ok(start_bag.chain(leftover_bags))
}
/// Insert several ids into the appropriate bags in the list. Continues with insertions
/// if duplicates are detected.
///