MCPcopy Create free account
hub / github.com/apache/datafusion / repeat_impl

Function repeat_impl

datafusion/functions/src/string/repeat.rs:257–324  ·  view source on GitHub ↗
(
    string_array: &S,
    number_array: &Int64Array,
    max_item_capacity: usize,
    mut builder: B,
)

Source from the content-addressed store, hash-verified

255}
256
257fn repeat_impl<'a, S, B>(
258 string_array: &S,
259 number_array: &Int64Array,
260 max_item_capacity: usize,
261 mut builder: B,
262) -> Result<ArrayRef>
263where
264 S: StringArrayType<'a> + 'a,
265 B: BulkNullStringArrayBuilder,
266{
267 // Reusable buffer to avoid allocations in string.repeat()
268 let mut buffer = Vec::<u8>::with_capacity(max_item_capacity);
269
270 // Helper function to repeat a string into a buffer using doubling strategy
271 // count must be > 0
272 #[inline]
273 fn repeat_to_buffer(buffer: &mut Vec<u8>, string: &str, count: usize) {
274 buffer.clear();
275 if !string.is_empty() {
276 let src = string.as_bytes();
277 // Initial copy
278 buffer.extend_from_slice(src);
279 // Doubling strategy: copy what we have so far until we reach the target
280 while buffer.len() < src.len() * count {
281 let copy_len = buffer.len().min(src.len() * count - buffer.len());
282 // SAFETY: we're copying valid UTF-8 bytes that we already verified
283 buffer.extend_from_within(..copy_len);
284 }
285 }
286 }
287
288 // Output is null IFF either input is null
289 let nulls = NullBuffer::union(string_array.nulls(), number_array.nulls());
290
291 if let Some(ref n) = nulls {
292 for i in 0..string_array.len() {
293 if n.is_null(i) {
294 builder.append_placeholder();
295 continue;
296 }
297 // SAFETY: index `i` in both arrays is valid
298 let string = unsafe { string_array.value_unchecked(i) };
299 let count = unsafe { number_array.value_unchecked(i) };
300 if count > 0 {
301 repeat_to_buffer(&mut buffer, string, count as usize);
302 // SAFETY: buffer contains valid UTF-8 since we only copy from a valid &str
303 builder.append_value(unsafe { std::str::from_utf8_unchecked(&buffer) });
304 } else {
305 builder.append_value("");
306 }
307 }
308 } else {
309 for i in 0..string_array.len() {
310 // SAFETY: no nulls, so every index in both arrays is valid
311 let string = unsafe { string_array.value_unchecked(i) };
312 let count = unsafe { number_array.value_unchecked(i) };
313 if count > 0 {
314 repeat_to_buffer(&mut buffer, string, count as usize);

Callers 1

repeatFunction · 0.85

Calls 8

repeat_to_bufferFunction · 0.85
append_placeholderMethod · 0.80
unionFunction · 0.50
nullsMethod · 0.45
lenMethod · 0.45
is_nullMethod · 0.45
append_valueMethod · 0.45
finishMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…