use crate::structs::bitmask::Bitmask;
pub trait Consolidate {
type Output;
fn consolidate(self) -> Self::Output;
}
pub fn extend_null_mask(
result_mask: &mut Option<Bitmask>,
result_len: usize,
source_mask: Option<&Bitmask>,
offset: usize,
len: usize,
) {
match (result_mask.as_mut(), source_mask) {
(Some(mask), Some(src)) => {
mask.extend((offset..offset + len).map(|i| src.get(i)));
}
(Some(mask), None) => {
for _ in 0..len {
mask.set(mask.len(), true);
}
}
(None, Some(src)) => {
let mut mask = Bitmask::new_set_all(result_len, true);
mask.extend((offset..offset + len).map(|i| src.get(i)));
*result_mask = Some(mask);
}
(None, None) => {}
}
}
#[cfg(feature = "chunked")]
impl<'a> Consolidate for Vec<crate::aliases::ArrayVT<'a>> {
type Output = crate::enums::array::Array;
fn consolidate(self) -> Self::Output {
use crate::enums::array::Array;
use crate::enums::collections::numeric_array::NumericArray;
use crate::enums::collections::text_array::TextArray;
#[cfg(feature = "datetime")]
use crate::enums::collections::temporal_array::TemporalArray;
use std::sync::Arc;
assert!(!self.is_empty(), "consolidate() called on empty Vec<ArrayVT>");
macro_rules! gather_numeric {
($variant:ident, $T:ty) => {{
let views: Vec<crate::aliases::IntegerAVT<'a, $T>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::NumericArray(NumericArray::$variant(a)) => (a.as_ref(), *off, *len),
_ => panic!(
"inconsistent NumericArray variants in chunk vector"
),
})
.collect();
Array::NumericArray(NumericArray::$variant(Arc::new(views.consolidate())))
}};
}
macro_rules! gather_float {
($variant:ident, $T:ty) => {{
let views: Vec<crate::aliases::FloatAVT<'a, $T>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::NumericArray(NumericArray::$variant(a)) => (a.as_ref(), *off, *len),
_ => panic!(
"inconsistent NumericArray variants in chunk vector"
),
})
.collect();
Array::NumericArray(NumericArray::$variant(Arc::new(views.consolidate())))
}};
}
macro_rules! gather_string {
($variant:ident, $T:ty) => {{
let views: Vec<crate::aliases::StringAVT<'a, $T>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::TextArray(TextArray::$variant(a)) => (a.as_ref(), *off, *len),
_ => panic!(
"inconsistent TextArray variants in chunk vector"
),
})
.collect();
Array::TextArray(TextArray::$variant(Arc::new(views.consolidate())))
}};
}
macro_rules! gather_categorical {
($variant:ident, $T:ty) => {{
let views: Vec<crate::aliases::CategoricalAVT<'a, $T>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::TextArray(TextArray::$variant(a)) => (a.as_ref(), *off, *len),
_ => panic!(
"inconsistent TextArray variants in chunk vector"
),
})
.collect();
Array::TextArray(TextArray::$variant(Arc::new(views.consolidate())))
}};
}
#[cfg(feature = "datetime")]
macro_rules! gather_datetime {
($variant:ident, $T:ty) => {{
let views: Vec<crate::aliases::DatetimeAVT<'a, $T>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::TemporalArray(TemporalArray::$variant(a)) => {
(a.as_ref(), *off, *len)
}
_ => panic!(
"inconsistent TemporalArray variants in chunk vector"
),
})
.collect();
Array::TemporalArray(TemporalArray::$variant(Arc::new(views.consolidate())))
}};
}
match self[0].0 {
Array::NumericArray(NumericArray::Int32(_)) => gather_numeric!(Int32, i32),
Array::NumericArray(NumericArray::Int64(_)) => gather_numeric!(Int64, i64),
Array::NumericArray(NumericArray::UInt32(_)) => gather_numeric!(UInt32, u32),
Array::NumericArray(NumericArray::UInt64(_)) => gather_numeric!(UInt64, u64),
Array::NumericArray(NumericArray::Float32(_)) => gather_float!(Float32, f32),
Array::NumericArray(NumericArray::Float64(_)) => gather_float!(Float64, f64),
#[cfg(feature = "extended_numeric_types")]
Array::NumericArray(NumericArray::Int8(_)) => gather_numeric!(Int8, i8),
#[cfg(feature = "extended_numeric_types")]
Array::NumericArray(NumericArray::Int16(_)) => gather_numeric!(Int16, i16),
#[cfg(feature = "extended_numeric_types")]
Array::NumericArray(NumericArray::UInt8(_)) => gather_numeric!(UInt8, u8),
#[cfg(feature = "extended_numeric_types")]
Array::NumericArray(NumericArray::UInt16(_)) => gather_numeric!(UInt16, u16),
Array::NumericArray(NumericArray::Null) => Array::Null,
Array::TextArray(TextArray::String32(_)) => gather_string!(String32, u32),
#[cfg(feature = "large_string")]
Array::TextArray(TextArray::String64(_)) => gather_string!(String64, u64),
#[cfg(any(not(feature = "default_categorical_8"), feature = "extended_categorical"))]
Array::TextArray(TextArray::Categorical32(_)) => gather_categorical!(Categorical32, u32),
#[cfg(feature = "default_categorical_8")]
Array::TextArray(TextArray::Categorical8(_)) => gather_categorical!(Categorical8, u8),
#[cfg(feature = "extended_categorical")]
Array::TextArray(TextArray::Categorical16(_)) => gather_categorical!(Categorical16, u16),
#[cfg(feature = "extended_categorical")]
Array::TextArray(TextArray::Categorical64(_)) => gather_categorical!(Categorical64, u64),
Array::TextArray(TextArray::Null) => Array::Null,
Array::BooleanArray(_) => {
let views: Vec<crate::aliases::BooleanAVT<'a, ()>> = self
.iter()
.map(|(arr, off, len)| match arr {
Array::BooleanArray(a) => (a.as_ref(), *off, *len),
_ => panic!("inconsistent Array variants in chunk vector"),
})
.collect();
Array::BooleanArray(Arc::new(views.consolidate()))
}
#[cfg(feature = "datetime")]
Array::TemporalArray(TemporalArray::Datetime32(_)) => gather_datetime!(Datetime32, i32),
#[cfg(feature = "datetime")]
Array::TemporalArray(TemporalArray::Datetime64(_)) => gather_datetime!(Datetime64, i64),
#[cfg(feature = "datetime")]
Array::TemporalArray(TemporalArray::Null) => Array::Null,
Array::Null => Array::Null,
}
}
}