Fast path for case conversion on an all-ASCII string array. ASCII case conversion is byte-length-preserving, so we can convert the entire addressed byte range in one pass over the value buffer and reuse the offsets and nulls buffers — rebasing the offsets when the input is a sliced array.
(
string_array: &GenericStringArray<O>,
lower: bool,
)
| 579 | /// byte range in one pass over the value buffer and reuse the offsets and nulls |
| 580 | /// buffers — rebasing the offsets when the input is a sliced array. |
| 581 | fn case_conversion_ascii_array<O: OffsetSizeTrait>( |
| 582 | string_array: &GenericStringArray<O>, |
| 583 | lower: bool, |
| 584 | ) -> Result<ArrayRef> { |
| 585 | let value_offsets = string_array.value_offsets(); |
| 586 | let start = value_offsets.first().unwrap().as_usize(); |
| 587 | let end = value_offsets.last().unwrap().as_usize(); |
| 588 | let relevant = &string_array.value_data()[start..end]; |
| 589 | |
| 590 | let converted: Vec<u8> = if lower { |
| 591 | relevant.iter().map(u8::to_ascii_lowercase).collect() |
| 592 | } else { |
| 593 | relevant.iter().map(u8::to_ascii_uppercase).collect() |
| 594 | }; |
| 595 | let values = Buffer::from_vec(converted); |
| 596 | |
| 597 | // Shift offsets from `start`-based to 0-based so they index into `values`. |
| 598 | let offsets = if start == 0 { |
| 599 | string_array.offsets().clone() |
| 600 | } else { |
| 601 | let s = O::usize_as(start); |
| 602 | let rebased: Vec<O> = value_offsets.iter().map(|&o| o - s).collect(); |
| 603 | // SAFETY: subtracting a constant from monotonic offsets preserves |
| 604 | // monotonicity, and `start` is the minimum offset, so no underflow. |
| 605 | unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(rebased)) } |
| 606 | }; |
| 607 | |
| 608 | let nulls = string_array.nulls().cloned(); |
| 609 | // SAFETY: offsets are monotonic and in-bounds for `values`; nulls |
| 610 | // (if any) match the slice length. |
| 611 | Ok(Arc::new(unsafe { |
| 612 | GenericStringArray::<O>::new_unchecked(offsets, values, nulls) |
| 613 | })) |
| 614 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…