mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
perf: small improvement to extend_sorted_vec (#21032)
This commit is contained in:
@@ -2,53 +2,42 @@ use alloc::vec::Vec;
|
||||
use core::cmp::Ordering;
|
||||
|
||||
/// Helper function to extend a sorted vector with another sorted vector.
|
||||
/// Values from `other` take precedence for duplicate keys.
|
||||
///
|
||||
/// This function efficiently merges two sorted vectors by:
|
||||
/// 1. Iterating through the target vector with mutable references
|
||||
/// 2. Using a peekable iterator for the other vector
|
||||
/// 3. For each target item, processing other items that come before or equal to it
|
||||
/// 4. Collecting items from other that need to be inserted
|
||||
/// 5. Appending and re-sorting only if new items were added
|
||||
/// Values from `other` take precedence for duplicate keys.
|
||||
pub(crate) fn extend_sorted_vec<K, V>(target: &mut Vec<(K, V)>, other: &[(K, V)])
|
||||
where
|
||||
K: Clone + Ord,
|
||||
V: Clone,
|
||||
{
|
||||
let cmp = |a: &(K, V), b: &(K, V)| a.0.cmp(&b.0);
|
||||
|
||||
if other.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut other_iter = other.iter().peekable();
|
||||
let mut to_insert = Vec::new();
|
||||
|
||||
// Iterate through target and update/collect items from other
|
||||
for target_item in target.iter_mut() {
|
||||
let initial_len = target.len();
|
||||
for i in 0..initial_len {
|
||||
while let Some(other_item) = other_iter.peek() {
|
||||
match other_item.0.cmp(&target_item.0) {
|
||||
let target_item = &mut target[i];
|
||||
match cmp(other_item, target_item) {
|
||||
Ordering::Less => {
|
||||
// Other item comes before current target item, collect it
|
||||
to_insert.push(other_iter.next().unwrap().clone());
|
||||
target.push(other_iter.next().unwrap().clone());
|
||||
}
|
||||
Ordering::Equal => {
|
||||
// Same key, update target with other's value
|
||||
target_item.1 = other_iter.next().unwrap().1.clone();
|
||||
break;
|
||||
}
|
||||
Ordering::Greater => {
|
||||
// Other item comes after current target item, keep target unchanged
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append collected new items, as well as any remaining from `other` which are necessarily also
|
||||
// new, and sort if needed
|
||||
if !to_insert.is_empty() || other_iter.peek().is_some() {
|
||||
target.extend(to_insert);
|
||||
target.extend(other_iter.cloned());
|
||||
target.sort_unstable_by(|a, b| a.0.cmp(&b.0));
|
||||
target.extend(other_iter.cloned());
|
||||
if target.len() > initial_len {
|
||||
target.sort_by(cmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user