diff --git a/crates/trie/common/src/utils.rs b/crates/trie/common/src/utils.rs index 2c30b474bc..a70608ea60 100644 --- a/crates/trie/common/src/utils.rs +++ b/crates/trie/common/src/utils.rs @@ -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(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); } }