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

Method from_bitwise_binary_op

arrow-buffer/src/buffer/boolean.rs:332–435  ·  view source on GitHub ↗

Create a new [`BooleanBuffer`] by applying the bitwise operation `op` to the relevant bits from two input buffers. This function is faster than applying the operation bit by bit as it processes input buffers in chunks of 64 bits (8 bytes) at a time # Notes: `op` takes two `u64` inputs and produces one `u64` output. `op` must only apply bitwise operations on the relevant bits; the input `u64` val

(
        left: impl AsRef<[u8]>,
        left_offset_in_bits: usize,
        right: impl AsRef<[u8]>,
        right_offset_in_bits: usize,
        len_in_bits: usize,
        mut op: F,
    )

Source from the content-addressed store, hash-verified

330 /// }
331 /// ```
332 pub fn from_bitwise_binary_op<F>(
333 left: impl AsRef<[u8]>,
334 left_offset_in_bits: usize,
335 right: impl AsRef<[u8]>,
336 right_offset_in_bits: usize,
337 len_in_bits: usize,
338 mut op: F,
339 ) -> Self
340 where
341 F: FnMut(u64, u64) -> u64,
342 {
343 let left = left.as_ref();
344 let right = right.as_ref();
345
346 // When both offsets share the same sub-64-bit alignment, we can
347 // align both to 64-bit boundaries and zip u64s directly,
348 // avoiding BitChunks bit-shifting entirely.
349 if left_offset_in_bits % 64 == right_offset_in_bits % 64 {
350 let bit_offset = left_offset_in_bits % 64;
351 let left_end = left_offset_in_bits + len_in_bits;
352 let right_end = right_offset_in_bits + len_in_bits;
353
354 let left_aligned = left_offset_in_bits & !63;
355 let right_aligned = right_offset_in_bits & !63;
356
357 let left_end_bytes = (bit_util::ceil(left_end, 64) * 8).min(left.len());
358 let right_end_bytes = (bit_util::ceil(right_end, 64) * 8).min(right.len());
359
360 let left_slice = &left[left_aligned / 8..left_end_bytes];
361 let right_slice = &right[right_aligned / 8..right_end_bytes];
362
363 let (lp, left_u64s, ls) = unsafe { left_slice.align_to::<u64>() };
364 let (rp, right_u64s, rs) = unsafe { right_slice.align_to::<u64>() };
365
366 match (lp, ls, rp, rs) {
367 ([], [], [], []) => {
368 let result_u64s: Vec<u64> = left_u64s
369 .iter()
370 .zip(right_u64s.iter())
371 .map(|(l, r)| op(*l, *r))
372 .collect();
373 return BooleanBuffer::new(result_u64s.into(), bit_offset, len_in_bits);
374 }
375 ([], left_suf, [], right_suf) => {
376 let left_iter = left_u64s
377 .iter()
378 .cloned()
379 .chain((!left_suf.is_empty()).then(|| read_u64(left_suf)));
380 let right_iter = right_u64s
381 .iter()
382 .cloned()
383 .chain((!right_suf.is_empty()).then(|| read_u64(right_suf)));
384 let result_u64s: Vec<u64> =
385 left_iter.zip(right_iter).map(|(l, r)| op(l, r)).collect();
386 return BooleanBuffer::new(result_u64s.into(), bit_offset, len_in_bits);
387 }
388 _ => {}
389 }

Callers

nothing calls this directly

Calls 12

collectMethod · 0.80
zipMethod · 0.80
remainder_lenMethod · 0.80
remainder_bitsMethod · 0.80
extend_from_sliceMethod · 0.80
ceilFunction · 0.50
read_u64Function · 0.50
as_refMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
is_emptyMethod · 0.45
to_le_bytesMethod · 0.45

Tested by

no test coverage detected