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/28 09:46:30 UTC

[arrow-rs] branch master updated: feat: support `bitwise` shift left/right (#4148)

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 67176f0f1 feat: support `bitwise` shift left/right (#4148)
67176f0f1 is described below

commit 67176f0f1ae925a76fdc2b09d541775cb76d1b67
Author: Alex Huang <hu...@gmail.com>
AuthorDate: Fri Apr 28 11:46:23 2023 +0200

    feat: support `bitwise` shift left/right (#4148)
    
    * feat: support bitwise shift left/right
    
    * ignore truncation
    
    * add test when shifting by more than the number of bits
---
 arrow-arith/src/bitwise.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arrow-arith/src/bitwise.rs b/arrow-arith/src/bitwise.rs
index 08cc246b3..f9f456bf9 100644
--- a/arrow-arith/src/bitwise.rs
+++ b/arrow-arith/src/bitwise.rs
@@ -17,7 +17,9 @@
 
 use crate::arity::{binary, unary};
 use arrow_array::*;
+use arrow_buffer::ArrowNativeType;
 use arrow_schema::ArrowError;
+use num::traits::{WrappingShl, WrappingShr};
 use std::ops::{BitAnd, BitOr, BitXor, Not};
 
 // The helper function for bitwise operation with two array
@@ -121,6 +123,38 @@ where
     Ok(unary(array, |value| value ^ scalar))
 }
 
+/// Perform bitwise 'left << right' operation on two arrays. If either left or right value is null
+/// then the result is also null.
+pub fn bitwise_shift_left<T>(
+    left: &PrimitiveArray<T>,
+    right: &PrimitiveArray<T>,
+) -> Result<PrimitiveArray<T>, ArrowError>
+where
+    T: ArrowNumericType,
+    T::Native: WrappingShl<Output = T::Native>,
+{
+    bitwise_op(left, right, |a, b| {
+        let b = b.as_usize();
+        a.wrapping_shl(b as u32)
+    })
+}
+
+/// Perform bitwise 'left >> right' operation on two arrays. If either left or right value is null
+/// then the result is also null.
+pub fn bitwise_shift_right<T>(
+    left: &PrimitiveArray<T>,
+    right: &PrimitiveArray<T>,
+) -> Result<PrimitiveArray<T>, ArrowError>
+where
+    T: ArrowNumericType,
+    T::Native: WrappingShr<Output = T::Native>,
+{
+    bitwise_op(left, right, |a, b| {
+        let b = b.as_usize();
+        a.wrapping_shr(b as u32)
+    })
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -143,6 +177,28 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn test_bitwise_shift_left() {
+        let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4), Some(8)]);
+        let right =
+            UInt64Array::from(vec![Some(5), Some(10), Some(8), Some(12), Some(u64::MAX)]);
+        let expected =
+            UInt64Array::from(vec![Some(32), Some(2048), None, Some(16384), Some(0)]);
+        let result = bitwise_shift_left(&left, &right).unwrap();
+        assert_eq!(expected, result);
+    }
+
+    #[test]
+    fn test_bitwise_shift_right() {
+        let left =
+            UInt64Array::from(vec![Some(32), Some(2048), None, Some(16384), Some(3)]);
+        let right =
+            UInt64Array::from(vec![Some(5), Some(10), Some(8), Some(12), Some(65)]);
+        let expected = UInt64Array::from(vec![Some(1), Some(2), None, Some(4), Some(1)]);
+        let result = bitwise_shift_right(&left, &right).unwrap();
+        assert_eq!(expected, result);
+    }
+
     #[test]
     fn test_bitwise_and_array_scalar() {
         // unsigned value