rluvaton commented on code in PR #8619:
URL: https://github.com/apache/arrow-rs/pull/8619#discussion_r2464104526


##########
arrow-buffer/src/buffer/mutable_ops.rs:
##########
@@ -0,0 +1,1256 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::{Buffer, MutableBuffer};
+use crate::BooleanBufferBuilder;
+use crate::bit_chunk_iterator::BitChunks;
+use crate::util::bit_util;
+
+/// What can be used as the right-hand side (RHS) buffer in mutable operations.
+///
+/// this is not mutated.
+///
+/// # Implementation notes
+///
+/// ## Why `pub(crate)`?
+/// This is because we don't want this trait to expose the inner buffer to the 
public.
+/// this is the trait implementor choice.
+///
+pub(crate) trait BufferSupportedRhs {
+    fn as_slice(&self) -> &[u8];
+}
+
+impl BufferSupportedRhs for Buffer {
+    fn as_slice(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl BufferSupportedRhs for MutableBuffer {
+    fn as_slice(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl BufferSupportedRhs for BooleanBufferBuilder {
+    fn as_slice(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+/// Trait that will be operated on as the left-hand side (LHS) buffer in 
mutable operations.
+///
+/// This consumer of the trait must satisfies the following guarantees:
+/// 1. It will not change the length of the buffer.
+///
+/// # Implementation notes
+///
+/// ## Why is this trait `pub(crate)`?
+/// Because we don't wanna expose the inner mutable buffer to the public.
+/// as this is the choice of the implementor of the trait and sometimes it is 
not desirable
+/// (e.g. `BooleanBufferBuilder`).
+///
+/// ## Why this trait is needed, can't we just use `MutableBuffer` directly?
+/// Sometimes we don't want to expose the inner `MutableBuffer`
+/// so it can't be misused.
+///
+/// For example, [`BooleanBufferBuilder`] does not expose the inner 
`MutableBuffer`
+/// as exposing it will allow the user to change the length of the buffer that 
will make the
+/// `BooleanBufferBuilder` invalid.
+///
+pub(crate) trait MutableOpsBufferSupportedLhs {
+    /// Get a mutable reference to the inner `MutableBuffer`.
+    ///
+    /// This is used to perform in-place operations on the buffer.
+    ///
+    /// the caller must ensure that the length of the buffer is not changed.
+    fn inner_mutable_buffer(&mut self) -> &mut MutableBuffer;
+}
+
+impl MutableOpsBufferSupportedLhs for MutableBuffer {
+    fn inner_mutable_buffer(&mut self) -> &mut MutableBuffer {
+        self
+    }
+}
+
+/// Apply a binary bitwise operation to two bit-packed buffers.
+///
+/// This is the main entry point for binary operations. It handles both 
byte-aligned
+/// and non-byte-aligned cases by delegating to specialized helper functions.
+///
+/// # Arguments
+///
+/// * `left` - The left mutable buffer to be modified in-place
+/// * `left_offset_in_bits` - Starting bit offset in the left buffer
+/// * `right` - The right buffer (as byte slice)
+/// * `right_offset_in_bits` - Starting bit offset in the right buffer
+/// * `len_in_bits` - Number of bits to process
+/// * `op` - Binary operation to apply (e.g., `|a, b| a & b`)
+///
+#[allow(
+    private_bounds,
+    reason = "MutableOpsBufferSupportedLhs and BufferSupportedRhs exposes the 
inner internals which is the implementor choice and we dont want to leak 
internals"
+)]
+pub fn mutable_bitwise_bin_op_helper<F>(
+    left: &mut impl MutableOpsBufferSupportedLhs,
+    left_offset_in_bits: usize,
+    right: &impl BufferSupportedRhs,
+    right_offset_in_bits: usize,
+    len_in_bits: usize,
+    mut op: F,
+) where
+    F: FnMut(u64, u64) -> u64,
+{
+    if len_in_bits == 0 {
+        return;
+    }
+
+    let mutable_buffer = left.inner_mutable_buffer();
+
+    let mutable_buffer_len = mutable_buffer.len();
+    let mutable_buffer_cap = mutable_buffer.capacity();
+
+    // offset inside a byte
+    let left_bit_offset = left_offset_in_bits % 8;
+
+    let is_mutable_buffer_byte_aligned = left_bit_offset == 0;
+
+    if is_mutable_buffer_byte_aligned {

Review Comment:
   in order to be `u128` we would want to change the function to get `u128`, 
but I wanted to keep similar API to `Buffer` ops.
   
   do you think we should change it?
   
   and the special case can be added later



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to