From 89d8e09e00f76c2e2e3bdf3b36873a2b654b7b19 Mon Sep 17 00:00:00 2001 From: Ritchie Vink Date: Thu, 3 Feb 2022 17:21:12 +0100 Subject: [PATCH] More to `into_mut` implementations (#801) --- src/array/boolean/mod.rs | 37 +++++++++++++++ src/array/utf8/mod.rs | 75 +++++++++++++++++++++++++++++++ tests/it/array/utf8/mod.rs | 1 + tests/it/array/utf8/to_mutable.rs | 14 ++++++ 4 files changed, 127 insertions(+) create mode 100644 tests/it/array/utf8/to_mutable.rs diff --git a/src/array/boolean/mod.rs b/src/array/boolean/mod.rs index 1e6768e244f..17b8b5dc6c8 100644 --- a/src/array/boolean/mod.rs +++ b/src/array/boolean/mod.rs @@ -2,6 +2,7 @@ use crate::{ bitmap::Bitmap, datatypes::{DataType, PhysicalType}, }; +use either::Either; use super::{display_fmt, Array}; @@ -95,6 +96,42 @@ impl BooleanArray { arr.validity = validity; arr } + + /// Try to convert this `BooleanArray` to a `MutableBooleanArray` + pub fn into_mut(self) -> Either { + use Either::*; + + if let Some(bitmap) = self.validity { + match bitmap.into_mut() { + Left(bitmap) => Left(BooleanArray::from_data( + self.data_type, + self.values, + Some(bitmap), + )), + Right(mutable_bitmap) => match self.values.into_mut() { + Left(immutable) => Left(BooleanArray::from_data( + self.data_type, + immutable, + Some(mutable_bitmap.into()), + )), + Right(mutable) => Right(MutableBooleanArray::from_data( + self.data_type, + mutable, + Some(mutable_bitmap), + )), + }, + } + } else { + match self.values.into_mut() { + Left(immutable) => Left(BooleanArray::from_data(self.data_type, immutable, None)), + Right(mutable) => Right(MutableBooleanArray::from_data( + self.data_type, + mutable, + None, + )), + } + } + } } // accessors diff --git a/src/array/utf8/mod.rs b/src/array/utf8/mod.rs index ec436c813b6..e5068de01c7 100644 --- a/src/array/utf8/mod.rs +++ b/src/array/utf8/mod.rs @@ -1,4 +1,5 @@ use crate::{bitmap::Bitmap, buffer::Buffer, datatypes::DataType}; +use either::Either; use super::{ display_fmt, @@ -177,6 +178,80 @@ impl Utf8Array { arr.validity = validity; arr } + + /// Try to convert this `Utf8Array` to a `MutableUtf8Array` + pub fn into_mut(self) -> Either> { + use Either::*; + if let Some(bitmap) = self.validity { + match bitmap.into_mut() { + Left(bitmap) => Left(Utf8Array::from_data( + self.data_type, + self.offsets, + self.values, + Some(bitmap), + )), + Right(mutable_bitmap) => match (self.values.get_vec(), self.offsets.get_vec()) { + (Left(immutable_values), Left(immutable_offsets)) => { + Left(Utf8Array::from_data( + self.data_type, + immutable_offsets, + immutable_values, + Some(mutable_bitmap.into()), + )) + } + (Left(immutable_values), Right(mutable_offsets)) => Left(Utf8Array::from_data( + self.data_type, + mutable_offsets.into(), + immutable_values, + Some(mutable_bitmap.into()), + )), + (Right(mutable_values), Left(immutable_offsets)) => Left(Utf8Array::from_data( + self.data_type, + immutable_offsets, + mutable_values.into(), + Some(mutable_bitmap.into()), + )), + (Right(mutable_values), Right(mutable_offsets)) => { + Right(MutableUtf8Array::from_data( + self.data_type, + mutable_offsets, + mutable_values, + Some(mutable_bitmap), + )) + } + }, + } + } else { + match (self.values.get_vec(), self.offsets.get_vec()) { + (Left(immutable_values), Left(immutable_offsets)) => Left(Utf8Array::from_data( + self.data_type, + immutable_offsets, + immutable_values, + None, + )), + (Left(immutable_values), Right(mutable_offsets)) => Left(Utf8Array::from_data( + self.data_type, + mutable_offsets.into(), + immutable_values, + None, + )), + (Right(mutable_values), Left(immutable_offsets)) => Left(Utf8Array::from_data( + self.data_type, + immutable_offsets, + mutable_values.into(), + None, + )), + (Right(mutable_values), Right(mutable_offsets)) => { + Right(MutableUtf8Array::from_data( + self.data_type, + mutable_offsets, + mutable_values, + None, + )) + } + } + } + } } // Accessors diff --git a/tests/it/array/utf8/mod.rs b/tests/it/array/utf8/mod.rs index ac007507330..9cf5c88bd38 100644 --- a/tests/it/array/utf8/mod.rs +++ b/tests/it/array/utf8/mod.rs @@ -1,6 +1,7 @@ use arrow2::{array::*, bitmap::Bitmap, buffer::Buffer, datatypes::DataType, error::Result}; mod mutable; +mod to_mutable; #[test] fn basics() { diff --git a/tests/it/array/utf8/to_mutable.rs b/tests/it/array/utf8/to_mutable.rs new file mode 100644 index 00000000000..12f52151c68 --- /dev/null +++ b/tests/it/array/utf8/to_mutable.rs @@ -0,0 +1,14 @@ +use arrow2::array::Utf8Array; + +#[test] +#[allow(clippy::redundant_clone)] +fn array_to_mutable() { + let array = Utf8Array::::from(&[Some("hello"), Some(" "), None]); + let mutable = array.into_mut().unwrap_right(); + + let array: Utf8Array = mutable.into(); + let array2 = array.clone(); + let maybe_mut = array2.into_mut(); + // the ref count is 2 we should not get a mutable. + assert!(maybe_mut.is_left()) +}