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 7e47fa648 support bitwise op: or,xor,not (#2716)
7e47fa648 is described below

commit 7e47fa6484e0951a58956b2a748486ef140c1cc4
Author: Kun Liu <[email protected]>
AuthorDate: Wed Sep 14 03:08:47 2022 +0800

    support bitwise op: or,xor,not (#2716)
---
 arrow/src/compute/kernels/bitwise.rs | 167 +++++++++++++++++++++++++++++++++--
 1 file changed, 162 insertions(+), 5 deletions(-)

diff --git a/arrow/src/compute/kernels/bitwise.rs 
b/arrow/src/compute/kernels/bitwise.rs
index 18b9f4bb7..2f3c9e490 100644
--- a/arrow/src/compute/kernels/bitwise.rs
+++ b/arrow/src/compute/kernels/bitwise.rs
@@ -19,7 +19,7 @@ use crate::array::PrimitiveArray;
 use crate::compute::{binary, unary};
 use crate::datatypes::ArrowNumericType;
 use crate::error::{ArrowError, Result};
-use std::ops::BitAnd;
+use std::ops::{BitAnd, BitOr, BitXor, Not};
 
 // The helper function for bitwise operation with two array
 fn bitwise_op<T, F>(
@@ -52,7 +52,43 @@ where
     bitwise_op(left, right, |a, b| a & b)
 }
 
-/// Perform bitwise and  every value in an array with the scalar. If any value 
in the array is null then the
+/// Perform `left | right` operation on two arrays. If either left or right 
value is null
+/// then the result is also null.
+pub fn bitwise_or<T>(
+    left: &PrimitiveArray<T>,
+    right: &PrimitiveArray<T>,
+) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: BitOr<Output = T::Native>,
+{
+    bitwise_op(left, right, |a, b| a | b)
+}
+
+/// Perform `left ^ right` operation on two arrays. If either left or right 
value is null
+/// then the result is also null.
+pub fn bitwise_xor<T>(
+    left: &PrimitiveArray<T>,
+    right: &PrimitiveArray<T>,
+) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: BitXor<Output = T::Native>,
+{
+    bitwise_op(left, right, |a, b| a ^ b)
+}
+
+/// Perform `!array` operation on array. If array value is null
+/// then the result is also null.
+pub fn bitwise_not<T>(array: &PrimitiveArray<T>) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: Not<Output = T::Native>,
+{
+    Ok(unary(array, |value| !value))
+}
+
+/// Perform bitwise `and` every value in an array with the scalar. If any 
value in the array is null then the
 /// result is also null.
 pub fn bitwise_and_scalar<T>(
     array: &PrimitiveArray<T>,
@@ -65,10 +101,39 @@ where
     Ok(unary(array, |value| value & scalar))
 }
 
+/// Perform bitwise `or` every value in an array with the scalar. If any value 
in the array is null then the
+/// result is also null.
+pub fn bitwise_or_scalar<T>(
+    array: &PrimitiveArray<T>,
+    scalar: T::Native,
+) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: BitOr<Output = T::Native>,
+{
+    Ok(unary(array, |value| value | scalar))
+}
+
+/// Perform bitwise `xor` every value in an array with the scalar. If any 
value in the array is null then the
+/// result is also null.
+pub fn bitwise_xor_scalar<T>(
+    array: &PrimitiveArray<T>,
+    scalar: T::Native,
+) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: BitXor<Output = T::Native>,
+{
+    Ok(unary(array, |value| value ^ scalar))
+}
+
 #[cfg(test)]
 mod tests {
     use crate::array::{Int32Array, UInt64Array};
-    use crate::compute::kernels::bitwise::{bitwise_and, bitwise_and_scalar};
+    use crate::compute::kernels::bitwise::{
+        bitwise_and, bitwise_and_scalar, bitwise_not, bitwise_or, 
bitwise_or_scalar,
+        bitwise_xor, bitwise_xor_scalar,
+    };
     use crate::error::Result;
 
     #[test]
@@ -82,7 +147,7 @@ mod tests {
 
         // signed value
         let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
-        let right = Int32Array::from(vec![Some(5), Some(10), Some(8), 
Some(12)]);
+        let right = Int32Array::from(vec![Some(5), Some(-10), Some(8), 
Some(12)]);
         let expected = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
         let result = bitwise_and(&left, &right)?;
         assert_eq!(expected, result);
@@ -100,10 +165,102 @@ mod tests {
 
         // signed value
         let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
-        let scalar = 20;
+        let scalar = -20;
         let expected = Int32Array::from(vec![Some(0), Some(0), None, Some(4)]);
         let result = bitwise_and_scalar(&left, scalar)?;
         assert_eq!(expected, result);
         Ok(())
     }
+
+    #[test]
+    fn test_bitwise_or_array() -> Result<()> {
+        // unsigned value
+        let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let right = UInt64Array::from(vec![Some(7), Some(5), Some(8), 
Some(13)]);
+        let expected = UInt64Array::from(vec![Some(7), Some(7), None, 
Some(13)]);
+        let result = bitwise_or(&left, &right)?;
+        assert_eq!(expected, result);
+
+        // signed value
+        let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let right = Int32Array::from(vec![Some(-7), Some(-5), Some(8), 
Some(13)]);
+        let expected = Int32Array::from(vec![Some(-7), Some(-5), None, 
Some(13)]);
+        let result = bitwise_or(&left, &right)?;
+        assert_eq!(expected, result);
+        Ok(())
+    }
+
+    #[test]
+    fn test_bitwise_not_array() -> Result<()> {
+        // unsigned value
+        let array = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let expected = UInt64Array::from(vec![
+            Some(18446744073709551614),
+            Some(18446744073709551613),
+            None,
+            Some(18446744073709551611),
+        ]);
+        let result = bitwise_not(&array)?;
+        assert_eq!(expected, result);
+        // signed value
+        let array = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let expected = Int32Array::from(vec![Some(-2), Some(-3), None, 
Some(-5)]);
+        let result = bitwise_not(&array)?;
+        assert_eq!(expected, result);
+        Ok(())
+    }
+
+    #[test]
+    fn test_bitwise_or_array_scalar() -> Result<()> {
+        // unsigned value
+        let left = UInt64Array::from(vec![Some(15), Some(2), None, Some(4)]);
+        let scalar = 7;
+        let expected = UInt64Array::from(vec![Some(15), Some(7), None, 
Some(7)]);
+        let result = bitwise_or_scalar(&left, scalar)?;
+        assert_eq!(expected, result);
+
+        // signed value
+        let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let scalar = 20;
+        let expected = Int32Array::from(vec![Some(21), Some(22), None, 
Some(20)]);
+        let result = bitwise_or_scalar(&left, scalar)?;
+        assert_eq!(expected, result);
+        Ok(())
+    }
+
+    #[test]
+    fn test_bitwise_xor_array() -> Result<()> {
+        // unsigned value
+        let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let right = UInt64Array::from(vec![Some(7), Some(5), Some(8), 
Some(13)]);
+        let expected = UInt64Array::from(vec![Some(6), Some(7), None, 
Some(9)]);
+        let result = bitwise_xor(&left, &right)?;
+        assert_eq!(expected, result);
+
+        // signed value
+        let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let right = Int32Array::from(vec![Some(-7), Some(5), Some(8), 
Some(-13)]);
+        let expected = Int32Array::from(vec![Some(-8), Some(7), None, 
Some(-9)]);
+        let result = bitwise_xor(&left, &right)?;
+        assert_eq!(expected, result);
+        Ok(())
+    }
+
+    #[test]
+    fn test_bitwise_xor_array_scalar() -> Result<()> {
+        // unsigned value
+        let left = UInt64Array::from(vec![Some(15), Some(2), None, Some(4)]);
+        let scalar = 7;
+        let expected = UInt64Array::from(vec![Some(8), Some(5), None, 
Some(3)]);
+        let result = bitwise_xor_scalar(&left, scalar)?;
+        assert_eq!(expected, result);
+
+        // signed value
+        let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
+        let scalar = -20;
+        let expected = Int32Array::from(vec![Some(-19), Some(-18), None, 
Some(-24)]);
+        let result = bitwise_xor_scalar(&left, scalar)?;
+        assert_eq!(expected, result);
+        Ok(())
+    }
 }

Reply via email to