@@ -4,11 +4,10 @@ use alloc::vec::Vec;
44/// Values from `other` take precedence for duplicate keys.
55///
66/// This function efficiently merges two sorted vectors by:
7- /// 1. Iterating through the target vector with mutable references
8- /// 2. Using a peekable iterator for the other vector
9- /// 3. For each target item, processing other items that come before or equal to it
10- /// 4. Collecting items from other that need to be inserted
11- /// 5. Appending and re-sorting only if new items were added
7+ /// 1. Using peekable iterators for both vectors to compare without consuming
8+ /// 2. Merging in one pass (O(n+m)) by always choosing the smaller element
9+ /// 3. Building the result in a pre-allocated vector
10+ /// 4. Replacing target with the merged result
1211pub ( crate ) fn extend_sorted_vec < K , V > ( target : & mut Vec < ( K , V ) > , other : & [ ( K , V ) ] )
1312where
1413 K : Clone + Ord ,
@@ -18,36 +17,44 @@ where
1817 return ;
1918 }
2019
20+ let mut result = Vec :: with_capacity ( target. len ( ) + other. len ( ) ) ;
21+ let mut target_iter = target. iter ( ) . peekable ( ) ;
2122 let mut other_iter = other. iter ( ) . peekable ( ) ;
22- let mut to_insert = Vec :: new ( ) ;
2323
24- // Iterate through target and update/collect items from other
25- for target_item in target. iter_mut ( ) {
26- while let Some ( other_item) = other_iter. peek ( ) {
27- use core:: cmp:: Ordering ;
28- match other_item. 0 . cmp ( & target_item. 0 ) {
29- Ordering :: Less => {
30- // Other item comes before current target item, collect it
31- to_insert. push ( other_iter. next ( ) . unwrap ( ) . clone ( ) ) ;
32- }
33- Ordering :: Equal => {
34- // Same key, update target with other's value
35- target_item. 1 = other_iter. next ( ) . unwrap ( ) . 1 . clone ( ) ;
36- break ;
37- }
38- Ordering :: Greater => {
39- // Other item comes after current target item, keep target unchanged
40- break ;
24+ loop {
25+ match ( target_iter. peek ( ) , other_iter. peek ( ) ) {
26+ ( Some ( target_item) , Some ( other_item) ) => {
27+ use core:: cmp:: Ordering ;
28+ match other_item. 0 . cmp ( & target_item. 0 ) {
29+ Ordering :: Less => {
30+ result. push ( other_iter. next ( ) . unwrap ( ) . clone ( ) ) ;
31+ }
32+ Ordering :: Equal => {
33+ // duplicate key, use other's value (takes precedence)
34+ result. push ( other_iter. next ( ) . unwrap ( ) . clone ( ) ) ;
35+ target_iter. next ( ) ;
36+ }
37+ Ordering :: Greater => {
38+ result. push ( target_iter. next ( ) . unwrap ( ) . clone ( ) ) ;
39+ }
4140 }
4241 }
42+ ( Some ( _) , None ) => {
43+ // Only target items remaining
44+ result. extend ( target_iter. cloned ( ) ) ;
45+ break ;
46+ }
47+ ( None , Some ( _) ) => {
48+ // Only other items remaining
49+ result. extend ( other_iter. cloned ( ) ) ;
50+ break ;
51+ }
52+ ( None , None ) => {
53+ // Both exhausted
54+ break ;
55+ }
4356 }
4457 }
4558
46- // Append collected new items, as well as any remaining from `other` which are necessarily also
47- // new, and sort if needed
48- if !to_insert. is_empty ( ) || other_iter. peek ( ) . is_some ( ) {
49- target. extend ( to_insert) ;
50- target. extend ( other_iter. cloned ( ) ) ;
51- target. sort_unstable_by ( |a, b| a. 0 . cmp ( & b. 0 ) ) ;
52- }
59+ * target = result;
5360}
0 commit comments