@@ -376,18 +376,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
376
376
pub fn apply_copy ( & mut self , copy : ProvenanceCopy < Prov > , range : AllocRange , repeat : u64 ) {
377
377
let shift_offset = |idx : u64 , offset : Size | offset + range. start + idx * range. size ;
378
378
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
+ } ) ) ;
384
387
}
385
388
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
+ ) ;
391
397
}
392
398
}
393
399
}
0 commit comments