MCPcopy Create free account
hub / github.com/apache/arrow-rs / repeat_slice_n_times

Method repeat_slice_n_times

arrow-buffer/src/buffer/mutable.rs:311–372  ·  view source on GitHub ↗

Adding to this mutable buffer `slice_to_repeat` repeated `repeat_count` times. # Example ## Repeat the same string bytes multiple times ``` # use arrow_buffer::buffer::MutableBuffer; let mut buffer = MutableBuffer::new(0); let bytes_to_repeat = b"ab"; buffer.repeat_slice_n_times(bytes_to_repeat, 3); assert_eq!(buffer.as_slice(), b"ababab"); ``` # Panics Panics if the repeated slice byte length

(
        &mut self,
        slice_to_repeat: &[T],
        repeat_count: usize,
    )

Source from the content-addressed store, hash-verified

309 /// length overflows `usize`, or if reserving the required capacity fails for the same
310 /// reasons as [`MutableBuffer::reserve`].
311 pub fn repeat_slice_n_times<T: ArrowNativeType>(
312 &mut self,
313 slice_to_repeat: &[T],
314 repeat_count: usize,
315 ) {
316 if repeat_count == 0 || slice_to_repeat.is_empty() {
317 return;
318 }
319
320 let bytes_to_repeat = size_of_val(slice_to_repeat);
321 let repeated_bytes = repeat_count
322 .checked_mul(bytes_to_repeat)
323 .expect("repeated slice byte length overflow");
324 self.len
325 .checked_add(repeated_bytes)
326 .expect("mutable buffer length overflow");
327
328 // Ensure capacity
329 self.reserve(repeated_bytes);
330
331 // Save the length before we do all the copies to know where to start from
332 let length_before = self.len;
333
334 // Copy the initial slice once so we can use doubling strategy on it
335 self.extend_from_slice(slice_to_repeat);
336
337 // This tracks how much bytes we have added by repeating so far
338 let added_repeats_length = bytes_to_repeat;
339 assert_eq!(
340 self.len - length_before,
341 added_repeats_length,
342 "should copy exactly the same number of bytes"
343 );
344
345 // Number of times the slice was repeated
346 let mut already_repeated_times = 1;
347
348 // We will use doubling strategy to fill the buffer in log(repeat_count) steps
349 while already_repeated_times < repeat_count {
350 // How many slices can we copy in this iteration
351 // (either double what we have, or just the remaining ones)
352 let number_of_slices_to_copy =
353 already_repeated_times.min(repeat_count - already_repeated_times);
354 let number_of_bytes_to_copy = number_of_slices_to_copy * bytes_to_repeat;
355
356 unsafe {
357 // Get to the start of the data before we started copying anything
358 let src = self.data.as_ptr().add(length_before) as *const u8;
359
360 // Go to the current location to copy to (end of current data)
361 let dst = self.data.as_ptr().add(self.len);
362
363 // SAFETY: the pointers are not overlapping as there is `number_of_bytes_to_copy` or less between them
364 std::ptr::copy_nonoverlapping(src, dst, number_of_bytes_to_copy)
365 }
366
367 // Advance the length by the amount of data we just copied (doubled)
368 self.len += number_of_bytes_to_copy;

Calls 7

extend_from_sliceMethod · 0.80
is_emptyMethod · 0.45
checked_mulMethod · 0.45
checked_addMethod · 0.45
reserveMethod · 0.45
addMethod · 0.45
as_ptrMethod · 0.45