Path: blob/main/crates/polars-arrow/src/array/list/mutable.rs
6939 views
use std::sync::Arc;12use polars_error::{PolarsResult, polars_err};3use polars_utils::pl_str::PlSmallStr;45use super::ListArray;6use crate::array::physical_binary::extend_validity;7use crate::array::{Array, MutableArray, TryExtend, TryExtendFromSelf, TryPush};8use crate::bitmap::MutableBitmap;9use crate::datatypes::{ArrowDataType, Field};10use crate::offset::{Offset, Offsets};11use crate::trusted_len::TrustedLen;1213/// The mutable version of [`ListArray`].14#[derive(Debug, Clone)]15pub struct MutableListArray<O: Offset, M: MutableArray> {16dtype: ArrowDataType,17offsets: Offsets<O>,18values: M,19validity: Option<MutableBitmap>,20}2122impl<O: Offset, M: MutableArray + Default> MutableListArray<O, M> {23/// Creates a new empty [`MutableListArray`].24pub fn new() -> Self {25let values = M::default();26let dtype = ListArray::<O>::default_datatype(values.dtype().clone());27Self::new_from(values, dtype, 0)28}2930/// Creates a new [`MutableListArray`] with a capacity.31pub fn with_capacity(capacity: usize) -> Self {32let values = M::default();33let dtype = ListArray::<O>::default_datatype(values.dtype().clone());3435let offsets = Offsets::<O>::with_capacity(capacity);36Self {37dtype,38offsets,39values,40validity: None,41}42}43}4445impl<O: Offset, M: MutableArray + Default> Default for MutableListArray<O, M> {46fn default() -> Self {47Self::new()48}49}5051impl<O: Offset, M: MutableArray> From<MutableListArray<O, M>> for ListArray<O> {52fn from(mut other: MutableListArray<O, M>) -> Self {53ListArray::new(54other.dtype,55other.offsets.into(),56other.values.as_box(),57other.validity.map(|x| x.into()),58)59}60}6162impl<O, M, I, T> TryExtend<Option<I>> for MutableListArray<O, M>63where64O: Offset,65M: MutableArray + TryExtend<Option<T>>,66I: IntoIterator<Item = Option<T>>,67{68fn try_extend<II: IntoIterator<Item = Option<I>>>(&mut self, iter: II) -> PolarsResult<()> {69let iter = iter.into_iter();70self.reserve(iter.size_hint().0);71for items in iter {72self.try_push(items)?;73}74Ok(())75}76}7778impl<O, M, I, T> TryPush<Option<I>> for MutableListArray<O, M>79where80O: Offset,81M: MutableArray + TryExtend<Option<T>>,82I: IntoIterator<Item = Option<T>>,83{84#[inline]85fn try_push(&mut self, item: Option<I>) -> PolarsResult<()> {86if let Some(items) = item {87let values = self.mut_values();88values.try_extend(items)?;89self.try_push_valid()?;90} else {91self.push_null();92}93Ok(())94}95}9697impl<O, M> TryExtendFromSelf for MutableListArray<O, M>98where99O: Offset,100M: MutableArray + TryExtendFromSelf,101{102fn try_extend_from_self(&mut self, other: &Self) -> PolarsResult<()> {103extend_validity(self.len(), &mut self.validity, &other.validity);104105self.values.try_extend_from_self(&other.values)?;106self.offsets.try_extend_from_self(&other.offsets)107}108}109110impl<O: Offset, M: MutableArray> MutableListArray<O, M> {111/// Creates a new [`MutableListArray`] from a [`MutableArray`] and capacity.112pub fn new_from(values: M, dtype: ArrowDataType, capacity: usize) -> Self {113let offsets = Offsets::<O>::with_capacity(capacity);114assert_eq!(values.len(), 0);115ListArray::<O>::get_child_field(&dtype);116Self {117dtype,118offsets,119values,120validity: None,121}122}123124/// Creates a new [`MutableListArray`] from a [`MutableArray`].125pub fn new_with_field(values: M, name: PlSmallStr, nullable: bool) -> Self {126let field = Box::new(Field::new(name, values.dtype().clone(), nullable));127let dtype = if O::IS_LARGE {128ArrowDataType::LargeList(field)129} else {130ArrowDataType::List(field)131};132Self::new_from(values, dtype, 0)133}134135/// Creates a new [`MutableListArray`] from a [`MutableArray`] and capacity.136pub fn new_with_capacity(values: M, capacity: usize) -> Self {137let dtype = ListArray::<O>::default_datatype(values.dtype().clone());138Self::new_from(values, dtype, capacity)139}140141/// Creates a new [`MutableListArray`] from a [`MutableArray`], [`Offsets`] and142/// [`MutableBitmap`].143pub fn new_from_mutable(144values: M,145offsets: Offsets<O>,146validity: Option<MutableBitmap>,147) -> Self {148assert_eq!(values.len(), offsets.last().to_usize());149let dtype = ListArray::<O>::default_datatype(values.dtype().clone());150Self {151dtype,152offsets,153values,154validity,155}156}157158#[inline]159/// Needs to be called when a valid value was extended to this array.160/// This is a relatively low level function, prefer `try_push` when you can.161pub fn try_push_valid(&mut self) -> PolarsResult<()> {162let total_length = self.values.len();163let offset = self.offsets.last().to_usize();164let length = total_length165.checked_sub(offset)166.ok_or_else(|| polars_err!(ComputeError: "overflow"))?;167168self.offsets.try_push(length)?;169if let Some(validity) = &mut self.validity {170validity.push(true)171}172Ok(())173}174175#[inline]176fn push_null(&mut self) {177self.offsets.extend_constant(1);178match &mut self.validity {179Some(validity) => validity.push(false),180None => self.init_validity(),181}182}183184/// Expand this array, using elements from the underlying backing array.185/// Assumes the expansion begins at the highest previous offset, or zero if186/// this [`MutableListArray`] is currently empty.187///188/// Panics if:189/// - the new offsets are not in monotonic increasing order.190/// - any new offset is not in bounds of the backing array.191/// - the passed iterator has no upper bound.192pub fn try_extend_from_lengths<II>(&mut self, iterator: II) -> PolarsResult<()>193where194II: TrustedLen<Item = Option<usize>> + Clone,195{196self.offsets197.try_extend_from_lengths(iterator.clone().map(|x| x.unwrap_or_default()))?;198if let Some(validity) = &mut self.validity {199validity.extend_from_trusted_len_iter(iterator.map(|x| x.is_some()))200}201assert_eq!(self.offsets.last().to_usize(), self.values.len());202Ok(())203}204205/// Returns the length of this array206#[inline]207pub fn len(&self) -> usize {208self.offsets.len_proxy()209}210211/// The values212pub fn mut_values(&mut self) -> &mut M {213&mut self.values214}215216/// The offsets217pub fn offsets(&self) -> &Offsets<O> {218&self.offsets219}220221/// The values222pub fn values(&self) -> &M {223&self.values224}225226fn init_validity(&mut self) {227let len = self.offsets.len_proxy();228229let mut validity = MutableBitmap::with_capacity(self.offsets.capacity());230validity.extend_constant(len, true);231validity.set(len - 1, false);232self.validity = Some(validity)233}234235/// Converts itself into an [`Array`].236pub fn into_arc(self) -> Arc<dyn Array> {237let a: ListArray<O> = self.into();238Arc::new(a)239}240241/// converts itself into [`Box<dyn Array>`]242pub fn into_box(self) -> Box<dyn Array> {243let a: ListArray<O> = self.into();244Box::new(a)245}246247/// Reserves `additional` slots.248pub fn reserve(&mut self, additional: usize) {249self.offsets.reserve(additional);250if let Some(x) = self.validity.as_mut() {251x.reserve(additional)252}253}254255/// Shrinks the capacity of the [`MutableListArray`] to fit its current length.256pub fn shrink_to_fit(&mut self) {257self.values.shrink_to_fit();258self.offsets.shrink_to_fit();259if let Some(validity) = &mut self.validity {260validity.shrink_to_fit()261}262}263}264265impl<O: Offset, M: MutableArray + 'static> MutableArray for MutableListArray<O, M> {266fn len(&self) -> usize {267MutableListArray::len(self)268}269270fn validity(&self) -> Option<&MutableBitmap> {271self.validity.as_ref()272}273274fn as_box(&mut self) -> Box<dyn Array> {275ListArray::new(276self.dtype.clone(),277std::mem::take(&mut self.offsets).into(),278self.values.as_box(),279std::mem::take(&mut self.validity).map(|x| x.into()),280)281.boxed()282}283284fn as_arc(&mut self) -> Arc<dyn Array> {285ListArray::new(286self.dtype.clone(),287std::mem::take(&mut self.offsets).into(),288self.values.as_box(),289std::mem::take(&mut self.validity).map(|x| x.into()),290)291.arced()292}293294fn dtype(&self) -> &ArrowDataType {295&self.dtype296}297298fn as_any(&self) -> &dyn std::any::Any {299self300}301302fn as_mut_any(&mut self) -> &mut dyn std::any::Any {303self304}305306#[inline]307fn push_null(&mut self) {308self.push_null()309}310311fn reserve(&mut self, additional: usize) {312self.reserve(additional)313}314315fn shrink_to_fit(&mut self) {316self.shrink_to_fit();317}318}319320321