@@ -360,18 +360,24 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
360
360
pub fn apply_copy ( & mut self , copy : ProvenanceCopy < Prov > , range : AllocRange , repeat : u64 ) {
361
361
let shift_offset = |idx : u64 , offset : Size | offset + range. start + idx * range. size ;
362
362
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
+ } ) ) ;
368
371
}
369
372
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
+ ) ;
375
381
}
376
382
}
377
383
}
0 commit comments