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

Function byte_substring

arrow-string/src/substring.rs:252–326  ·  view source on GitHub ↗
(
    array: &GenericByteArray<T>,
    start: T::Offset,
    length: Option<T::Offset>,
)

Source from the content-addressed store, hash-verified

250}
251
252fn byte_substring<T: ByteArrayType>(
253 array: &GenericByteArray<T>,
254 start: T::Offset,
255 length: Option<T::Offset>,
256) -> Result<ArrayRef, ArrowError>
257where
258 <T as ByteArrayType>::Native: PartialEq,
259{
260 let offsets = array.value_offsets();
261 let data = array.value_data();
262 let zero = <T::Offset as Zero>::zero();
263
264 // When array is [Large]StringArray, we will check whether `offset` is at a valid char boundary.
265 let check_char_boundary = {
266 |offset: T::Offset| {
267 if !matches!(T::DATA_TYPE, DataType::Utf8 | DataType::LargeUtf8) {
268 return Ok(offset);
269 }
270 // Safety: a StringArray must contain valid UTF8 data
271 let data_str = unsafe { std::str::from_utf8_unchecked(data) };
272 let offset_usize = offset.as_usize();
273 if data_str.is_char_boundary(offset_usize) {
274 Ok(offset)
275 } else {
276 Err(ArrowError::ComputeError(format!(
277 "The offset {offset_usize} is at an invalid utf-8 boundary."
278 )))
279 }
280 }
281 };
282
283 // start and end offsets of all substrings
284 let mut new_starts_ends: Vec<(T::Offset, T::Offset)> = Vec::with_capacity(array.len());
285 let mut new_offsets: Vec<T::Offset> = Vec::with_capacity(array.len() + 1);
286 let mut len_so_far = zero;
287 new_offsets.push(zero);
288
289 offsets
290 .windows(2)
291 .try_for_each(|pair| -> Result<(), ArrowError> {
292 let new_start = match start.cmp(&zero) {
293 Ordering::Greater => check_char_boundary((pair[0] + start).min(pair[1]))?,
294 Ordering::Equal => pair[0],
295 Ordering::Less => check_char_boundary((pair[1] + start).max(pair[0]))?,
296 };
297 let new_end = match length {
298 Some(length) => check_char_boundary((length + new_start).min(pair[1]))?,
299 None => pair[1],
300 };
301 len_so_far += new_end - new_start;
302 new_starts_ends.push((new_start, new_end));
303 new_offsets.push(len_so_far);
304 Ok(())
305 })?;
306
307 // concatenate substrings into a buffer
308 let mut new_values = MutableBuffer::new(new_offsets.last().unwrap().as_usize());
309

Callers 1

substringFunction · 0.85

Calls 14

as_usizeMethod · 0.80
maxMethod · 0.80
extend_from_sliceMethod · 0.80
and_thenMethod · 0.80
slicedMethod · 0.80
value_offsetsMethod · 0.45
value_dataMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45
cmpMethod · 0.45
lastMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected