Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Add Array::with_validity (#399)
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 authored Sep 13, 2021
1 parent 62ba59e commit 227ab3b
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 1 deletion.
15 changes: 15 additions & 0 deletions src/array/binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ impl<O: Offset> BinaryArray<O> {
offset: self.offset + offset,
}
}

/// Sets the validity bitmap on this [`BinaryArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}
}

// accessors
Expand Down Expand Up @@ -159,6 +171,9 @@ impl<O: Offset> Array for BinaryArray<O> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl<O: Offset> std::fmt::Display for BinaryArray<O> {
Expand Down
15 changes: 15 additions & 0 deletions src/array/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ impl BooleanArray {
pub fn values(&self) -> &Bitmap {
&self.values
}

/// Sets the validity bitmap on this [`BooleanArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}
}

impl Array for BooleanArray {
Expand Down Expand Up @@ -118,6 +130,9 @@ impl Array for BooleanArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl std::fmt::Display for BooleanArray {
Expand Down
15 changes: 15 additions & 0 deletions src/array/dictionary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ impl<K: DictionaryKey> DictionaryArray<K> {
}
}

/// Sets the validity bitmap on this [`Array`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.values = Arc::from(arr.values.with_validity(validity));
arr
}

/// Returns the keys of the [`DictionaryArray`]. These keys can be used to fetch values
/// from `values`.
#[inline]
Expand Down Expand Up @@ -137,6 +149,9 @@ impl<K: DictionaryKey> Array for DictionaryArray<K> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl<K: DictionaryKey> std::fmt::Display for DictionaryArray<K>
Expand Down
15 changes: 15 additions & 0 deletions src/array/fixed_size_binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ impl FixedSizeBinaryArray {
pub fn size(&self) -> usize {
self.size as usize
}

/// Sets the validity bitmap on this [`FixedSizeBinaryArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}
}

impl FixedSizeBinaryArray {
Expand Down Expand Up @@ -128,6 +140,9 @@ impl Array for FixedSizeBinaryArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl std::fmt::Display for FixedSizeBinaryArray {
Expand Down
15 changes: 15 additions & 0 deletions src/array/fixed_size_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ impl FixedSizeListArray {
self.values
.slice(i * self.size as usize, self.size as usize)
}

/// Sets the validity bitmap on this [`FixedSizeListArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}
}

impl FixedSizeListArray {
Expand Down Expand Up @@ -131,6 +143,9 @@ impl Array for FixedSizeListArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl std::fmt::Display for FixedSizeListArray {
Expand Down
15 changes: 15 additions & 0 deletions src/array/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ impl<O: Offset> ListArray<O> {
pub fn values(&self) -> &Arc<dyn Array> {
&self.values
}

/// Sets the validity bitmap on this [`ListArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}
}

impl<O: Offset> ListArray<O> {
Expand Down Expand Up @@ -174,6 +186,9 @@ impl<O: Offset> Array for ListArray<O> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl<O: Offset> std::fmt::Display for ListArray<O> {
Expand Down
5 changes: 5 additions & 0 deletions src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ pub trait Array: std::fmt::Debug + Send + Sync {
/// # Panic
/// This function panics iff `offset + length >= self.len()`.
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array>;

/// Sets the validity bitmap on this [`Array`].
/// # Panic
/// This function panics iff `validity.len() < self.len()`.
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array>;
}

/// A trait describing a mutable array; i.e. an array whose values can be changed.
Expand Down
3 changes: 3 additions & 0 deletions src/array/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ impl Array for NullArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, _: Option<Bitmap>) -> Box<dyn Array> {
panic!("cannot set validity of a null array")
}
}

impl std::fmt::Display for NullArray {
Expand Down
15 changes: 15 additions & 0 deletions src/array/primitive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ impl<T: NativeType> PrimitiveArray<T> {
}
}

/// Sets the validity bitmap on this [`PrimitiveArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}

/// The values [`Buffer`].
#[inline]
pub fn values(&self) -> &Buffer<T> {
Expand Down Expand Up @@ -162,6 +174,9 @@ impl<T: NativeType> Array for PrimitiveArray<T> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

/// A type definition [`PrimitiveArray`] for `i8`
Expand Down
15 changes: 15 additions & 0 deletions src/array/struct_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ impl StructArray {
}
}

/// Sets the validity bitmap on this [`StructArray`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}

/// Returns the values of this [`StructArray`].
pub fn values(&self) -> &[Arc<dyn Array>] {
&self.values
Expand Down Expand Up @@ -163,6 +175,9 @@ impl Array for StructArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl std::fmt::Display for StructArray {
Expand Down
3 changes: 3 additions & 0 deletions src/array/union/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ impl Array for UnionArray {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, _: Option<Bitmap>) -> Box<dyn Array> {
panic!("cannot set validity of a union array")
}
}

impl UnionArray {
Expand Down
15 changes: 15 additions & 0 deletions src/array/utf8/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ impl<O: Offset> Utf8Array<O> {
}
}

/// Sets the validity bitmap on this [`Utf8Array`].
/// # Panic
/// This function panics iff `validity.len() != self.len()`.
pub fn with_validity(&self, validity: Option<Bitmap>) -> Self {
if matches!(&validity, Some(bitmap) if bitmap.len() != self.len()) {
panic!("validity should be as least as large as the array")
}
let mut arr = self.clone();
arr.validity = validity;
arr
}

/// Returns the element at index `i` as &str
pub fn value(&self, i: usize) -> &str {
let offsets = self.offsets.as_slice();
Expand Down Expand Up @@ -199,6 +211,9 @@ impl<O: Offset> Array for Utf8Array<O> {
fn slice(&self, offset: usize, length: usize) -> Box<dyn Array> {
Box::new(self.slice(offset, length))
}
fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
Box::new(self.with_validity(validity))
}
}

impl<O: Offset> std::fmt::Display for Utf8Array<O> {
Expand Down
15 changes: 14 additions & 1 deletion tests/it/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ mod primitive;
mod union;
mod utf8;

use arrow2::array::{clone, new_empty_array, new_null_array};
use arrow2::array::{clone, new_empty_array, new_null_array, Array, PrimitiveArray};
use arrow2::bitmap::Bitmap;
use arrow2::datatypes::PhysicalType::Primitive;
use arrow2::datatypes::{DataType, Field};

#[test]
Expand Down Expand Up @@ -68,3 +70,14 @@ fn test_clone() {
.all(|x| clone(new_null_array(x.clone(), 10).as_ref()) == new_null_array(x, 10));
assert!(a);
}

#[test]
fn test_with_validity() {
let arr = PrimitiveArray::from_slice(&[1i32, 2, 3]);
let validity = Bitmap::from(&[true, false, true]);
let arr = arr.with_validity(Some(validity));
let arr_ref = arr.as_any().downcast_ref::<PrimitiveArray<i32>>().unwrap();

let expected = PrimitiveArray::from(&[Some(1i32), None, Some(3)]);
assert_eq!(arr_ref, &expected);
}

0 comments on commit 227ab3b

Please sign in to comment.