You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2023/04/02 16:05:08 UTC
[arrow-rs] branch master updated: feat: add the implementation BitXor to BooleanBuffer (#3997)
This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new ecd44fd4c feat: add the implementation BitXor to BooleanBuffer (#3997)
ecd44fd4c is described below
commit ecd44fd4cd1ab65533979983791d5ef524a2eac6
Author: Igor Izvekov <iz...@mail.ru>
AuthorDate: Sun Apr 2 19:05:01 2023 +0300
feat: add the implementation BitXor to BooleanBuffer (#3997)
* feat: add the implementation BitXor to BooleanBuffer
* feat: add tests to "BooleanBuffer" for BitAnd, BitOr, BitXor, Not
---
arrow-buffer/src/buffer/boolean.rs | 87 +++++++++++++++++++++++++++++++++++++-
arrow-buffer/src/buffer/ops.rs | 25 +++++++++++
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/arrow-buffer/src/buffer/boolean.rs b/arrow-buffer/src/buffer/boolean.rs
index c89cfb332..2202e46d2 100644
--- a/arrow-buffer/src/buffer/boolean.rs
+++ b/arrow-buffer/src/buffer/boolean.rs
@@ -18,9 +18,10 @@
use crate::bit_chunk_iterator::BitChunks;
use crate::bit_iterator::{BitIndexIterator, BitIterator, BitSliceIterator};
use crate::{
- bit_util, buffer_bin_and, buffer_bin_or, buffer_unary_not, Buffer, MutableBuffer,
+ bit_util, buffer_bin_and, buffer_bin_or, buffer_bin_xor, buffer_unary_not, Buffer,
+ MutableBuffer,
};
-use std::ops::{BitAnd, BitOr, Not};
+use std::ops::{BitAnd, BitOr, BitXor, Not};
/// A slice-able [`Buffer`] containing bit-packed booleans
#[derive(Debug, Clone, Eq)]
@@ -236,6 +237,25 @@ impl BitOr<&BooleanBuffer> for &BooleanBuffer {
}
}
+impl BitXor<&BooleanBuffer> for &BooleanBuffer {
+ type Output = BooleanBuffer;
+
+ fn bitxor(self, rhs: &BooleanBuffer) -> Self::Output {
+ assert_eq!(self.len, rhs.len);
+ BooleanBuffer {
+ buffer: buffer_bin_xor(
+ &self.buffer,
+ self.offset,
+ &rhs.buffer,
+ rhs.offset,
+ self.len,
+ ),
+ offset: 0,
+ len: self.len,
+ }
+ }
+}
+
impl<'a> IntoIterator for &'a BooleanBuffer {
type Item = bool;
type IntoIter = BitIterator<'a>;
@@ -244,3 +264,66 @@ impl<'a> IntoIterator for &'a BooleanBuffer {
BitIterator::new(self.values(), self.offset, self.len)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_bitand() {
+ let offset = 0;
+ let len = 40;
+
+ let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
+ let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
+
+ let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
+ let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
+
+ let expected = BooleanBuffer::new(Buffer::from(&[0, 1, 1, 0, 0]), offset, len);
+ assert_eq!(boolean_buf1 & boolean_buf2, expected);
+ }
+
+ #[test]
+ fn test_bitor() {
+ let offset = 0;
+ let len = 40;
+
+ let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
+ let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
+
+ let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
+ let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
+
+ let expected = BooleanBuffer::new(Buffer::from(&[0, 1, 1, 1, 0]), offset, len);
+ assert_eq!(boolean_buf1 | boolean_buf2, expected);
+ }
+
+ #[test]
+ fn test_bitxor() {
+ let offset = 0;
+ let len = 40;
+
+ let buf1 = Buffer::from(&[0, 1, 1, 0, 0]);
+ let boolean_buf1 = &BooleanBuffer::new(buf1, offset, len);
+
+ let buf2 = Buffer::from(&[0, 1, 1, 1, 0]);
+ let boolean_buf2 = &BooleanBuffer::new(buf2, offset, len);
+
+ let expected = BooleanBuffer::new(Buffer::from(&[0, 0, 0, 1, 0]), offset, len);
+ assert_eq!(boolean_buf1 ^ boolean_buf2, expected);
+ }
+
+ #[test]
+ fn test_not() {
+ let offset = 0;
+ let len = 40;
+
+ let buf = Buffer::from(&[0, 1, 1, 0, 0]);
+ let boolean_buf = &BooleanBuffer::new(buf, offset, len);
+
+ let expected =
+ BooleanBuffer::new(Buffer::from(&[255, 254, 254, 255, 255]), offset, len);
+ assert_eq!(!boolean_buf, expected);
+ }
+}
diff --git a/arrow-buffer/src/buffer/ops.rs b/arrow-buffer/src/buffer/ops.rs
index 87dc5c003..eccff6280 100644
--- a/arrow-buffer/src/buffer/ops.rs
+++ b/arrow-buffer/src/buffer/ops.rs
@@ -125,6 +125,8 @@ where
result.into()
}
+/// Apply a bitwise and to two inputs and return the result as a Buffer.
+/// The inputs are treated as bitmaps, meaning that offsets and length are specified in number of bits.
pub fn buffer_bin_and(
left: &Buffer,
left_offset_in_bits: usize,
@@ -142,6 +144,8 @@ pub fn buffer_bin_and(
)
}
+/// Apply a bitwise or to two inputs and return the result as a Buffer.
+/// The inputs are treated as bitmaps, meaning that offsets and length are specified in number of bits.
pub fn buffer_bin_or(
left: &Buffer,
left_offset_in_bits: usize,
@@ -159,6 +163,27 @@ pub fn buffer_bin_or(
)
}
+/// Apply a bitwise xor to two inputs and return the result as a Buffer.
+/// The inputs are treated as bitmaps, meaning that offsets and length are specified in number of bits.
+pub fn buffer_bin_xor(
+ left: &Buffer,
+ left_offset_in_bits: usize,
+ right: &Buffer,
+ right_offset_in_bits: usize,
+ len_in_bits: usize,
+) -> Buffer {
+ bitwise_bin_op_helper(
+ left,
+ left_offset_in_bits,
+ right,
+ right_offset_in_bits,
+ len_in_bits,
+ |a, b| a ^ b,
+ )
+}
+
+/// Apply a bitwise not to one input and return the result as a Buffer.
+/// The input is treated as a bitmap, meaning that offset and length are specified in number of bits.
pub fn buffer_unary_not(
left: &Buffer,
offset_in_bits: usize,