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

Function take_bytes

arrow-select/src/take.rs:494–622  ·  view source on GitHub ↗

`take` implementation for string arrays

(
    array: &GenericByteArray<T>,
    indices: &PrimitiveArray<IndexType>,
)

Source from the content-addressed store, hash-verified

492
493/// `take` implementation for string arrays
494fn take_bytes<T: ByteArrayType, IndexType: ArrowPrimitiveType>(
495 array: &GenericByteArray<T>,
496 indices: &PrimitiveArray<IndexType>,
497) -> Result<GenericByteArray<T>, ArrowError> {
498 let mut values: Vec<u8> = Vec::new();
499 let mut offsets = Vec::with_capacity(indices.len() + 1);
500 offsets.push(T::Offset::default());
501
502 let input_offsets = array.value_offsets();
503 let mut capacity = 0;
504 let nulls = take_nulls(array.nulls(), indices);
505
506 // Branch on output nulls — `None` means every output slot is valid.
507 match nulls.as_ref().filter(|n| n.null_count() > 0) {
508 // Fast path: no nulls in output, every index is valid.
509 None => {
510 for index in indices.values() {
511 let index = index.as_usize();
512 let start = input_offsets[index].as_usize();
513 let end = input_offsets[index + 1].as_usize();
514 capacity += end - start;
515 offsets.push(
516 T::Offset::from_usize(capacity)
517 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?,
518 );
519 }
520
521 values.reserve(capacity);
522
523 let dst = values.spare_capacity_mut();
524 debug_assert!(dst.len() >= capacity);
525 let mut offset = 0;
526
527 for index in indices.values() {
528 // SAFETY: in-bounds proven by the first loop's bounds-checked offset access.
529 // dst asserted above to include the required capacity.
530 unsafe {
531 let data: &[u8] = array.value_unchecked(index.as_usize()).as_ref();
532 std::ptr::copy_nonoverlapping(
533 data.as_ptr(),
534 dst.get_unchecked_mut(offset..).as_mut_ptr().cast::<u8>(),
535 data.len(),
536 );
537 offset += data.len();
538 }
539 }
540
541 // SAFETY: wrote exactly `capacity` bytes above; reserved on line above.
542 unsafe {
543 values.set_len(capacity);
544 }
545 }
546 // Nullable path: only process valid (non-null) output positions.
547 Some(output_nulls) => {
548 let mut source_ranges = Vec::with_capacity(indices.len() - output_nulls.null_count());
549 let mut last_filled = 0;
550
551 // Pre-fill offsets; we overwrite valid positions below.

Callers

nothing calls this directly

Calls 15

defaultFunction · 0.85
take_nullsFunction · 0.85
filterMethod · 0.80
as_usizeMethod · 0.80
as_mut_ptrMethod · 0.80
set_lenMethod · 0.80
valid_indicesMethod · 0.80
lenMethod · 0.45
pushMethod · 0.45
value_offsetsMethod · 0.45
nullsMethod · 0.45
as_refMethod · 0.45

Tested by

no test coverage detected