@@ -360,18 +360,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
360360 pub fn apply_copy ( & mut self , copy : ProvenanceCopy < Prov > , range : AllocRange , repeat : u64 ) {
361361 let shift_offset = |idx : u64 , offset : Size | offset + range. start + idx * range. size ;
362362 if !copy. ptrs . is_empty ( ) {
363- for i in 0 ..repeat {
364- self . ptrs . insert_presorted (
365- copy. ptrs . iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ,
366- ) ;
367- }
363+ // We want to call `insert_presorted` only once so that, if possible, the entries
364+ // after the range we insert are moved back only once.
365+ let chunk_len = copy. ptrs . len ( ) as u64 ;
366+ self . ptrs . insert_presorted ( ( 0 ..chunk_len * repeat) . map ( |i| {
367+ let chunk = i / chunk_len;
368+ let ( offset, reloc) = copy. ptrs [ ( i % chunk_len) as usize ] ;
369+ ( shift_offset ( chunk, offset) , reloc)
370+ } ) ) ;
368371 }
369372 if !copy. bytes . is_empty ( ) {
370- for i in 0 ..repeat {
371- self . bytes . get_or_insert_with ( Box :: default) . insert_presorted (
372- copy. bytes . iter ( ) . map ( |& ( offset, reloc) | ( shift_offset ( i, offset) , reloc) ) ,
373- ) ;
374- }
373+ let chunk_len = copy. bytes . len ( ) as u64 ;
374+ self . bytes . get_or_insert_with ( Box :: default) . insert_presorted (
375+ ( 0 ..chunk_len * repeat) . map ( |i| {
376+ let chunk = i / chunk_len;
377+ let ( offset, reloc) = copy. bytes [ ( i % chunk_len) as usize ] ;
378+ ( shift_offset ( chunk, offset) , reloc)
379+ } ) ,
380+ ) ;
375381 }
376382 }
377383}
0 commit comments