`take` implementation for string arrays
(
array: &GenericByteArray<T>,
indices: &PrimitiveArray<IndexType>,
)
| 492 | |
| 493 | /// `take` implementation for string arrays |
| 494 | fn 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. |
nothing calls this directly
no test coverage detected