@@ -376,18 +376,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
376376 pub fn apply_copy ( & mut self , copy : ProvenanceCopy < Prov > , range : AllocRange , repeat : u64 ) {
377377 let shift_offset = |idx : u64 , offset : Size | offset + range. start + idx * range. size ;
378378 if !copy. ptrs . is_empty ( ) {
379- for i in 0 ..repeat {
380- self . ptrs . insert_presorted (
381- copy. ptrs . iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ,
382- ) ;
383- }
379+ // We want to call `insert_presorted` only once so that, if possible, the entries
380+ // after the range we insert are moved back only once.
381+ let chunk_len = copy. ptrs . len ( ) as u64 ;
382+ self . ptrs . insert_presorted ( ( 0 ..chunk_len * repeat) . map ( |i| {
383+ let chunk = i / chunk_len;
384+ let ( offset, reloc) = copy. ptrs [ ( i % chunk_len) as usize ] ;
385+ ( shift_offset ( chunk, offset) , reloc)
386+ } ) ) ;
384387 }
385388 if !copy. bytes . is_empty ( ) {
386- for i in 0 ..repeat {
387- self . bytes . get_or_insert_with ( Box :: default) . insert_presorted (
388- copy. bytes . iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ,
389- ) ;
390- }
389+ let chunk_len = copy. bytes . len ( ) as u64 ;
390+ self . bytes . get_or_insert_with ( Box :: default) . insert_presorted (
391+ ( 0 ..chunk_len * repeat) . map ( |i| {
392+ let chunk = i / chunk_len;
393+ let ( offset, reloc) = copy. bytes [ ( i % chunk_len) as usize ] ;
394+ ( shift_offset ( chunk, offset) , reloc)
395+ } ) ,
396+ ) ;
391397 }
392398 }
393399}
0 commit comments