Path: blob/main/crates/polars-arrow/src/legacy/array/list.rs
6939 views
use polars_error::PolarsResult;12use crate::array::{Array, ArrayRef, ListArray, NullArray, new_null_array};3use crate::bitmap::BitmapBuilder;4use crate::compute::concatenate;5use crate::datatypes::ArrowDataType;6use crate::legacy::array::is_nested_null;7use crate::legacy::prelude::*;8use crate::offset::Offsets;910pub struct AnonymousBuilder<'a> {11arrays: Vec<&'a dyn Array>,12offsets: Vec<i64>,13validity: Option<BitmapBuilder>,14size: i64,15}1617impl<'a> AnonymousBuilder<'a> {18pub fn new(size: usize) -> Self {19let mut offsets = Vec::with_capacity(size + 1);20offsets.push(0i64);21Self {22arrays: Vec::with_capacity(size),23offsets,24validity: None,25size: 0,26}27}28#[inline]29fn last_offset(&self) -> i64 {30*self.offsets.last().unwrap()31}3233pub fn is_empty(&self) -> bool {34self.offsets.len() == 135}3637pub fn offsets(&self) -> &[i64] {38&self.offsets39}4041pub fn take_offsets(self) -> Offsets<i64> {42// SAFETY: offsets are correct43unsafe { Offsets::new_unchecked(self.offsets) }44}4546#[inline]47pub fn push(&mut self, arr: &'a dyn Array) {48self.size += arr.len() as i64;49self.offsets.push(self.size);50self.arrays.push(arr);5152if let Some(validity) = &mut self.validity {53validity.push(true)54}55}5657pub fn push_multiple(&mut self, arrs: &'a [ArrayRef]) {58for arr in arrs {59self.size += arr.len() as i64;60self.arrays.push(arr.as_ref());61}62self.offsets.push(self.size);63self.update_validity()64}6566#[inline]67pub fn push_null(&mut self) {68self.offsets.push(self.last_offset());69match &mut self.validity {70Some(validity) => validity.push(false),71None => self.init_validity(),72}73}7475#[inline]76pub fn push_opt(&mut self, arr: Option<&'a dyn Array>) {77match arr {78None => self.push_null(),79Some(arr) => self.push(arr),80}81}8283pub fn push_empty(&mut self) {84self.offsets.push(self.last_offset());85self.update_validity()86}8788fn init_validity(&mut self) {89let len = self.offsets.len() - 1;90let mut validity = BitmapBuilder::with_capacity(self.offsets.capacity());91if len > 0 {92validity.extend_constant(len - 1, true);93validity.push(false);94}95self.validity = Some(validity)96}9798fn update_validity(&mut self) {99if let Some(validity) = &mut self.validity {100validity.push(true)101}102}103104pub fn finish(self, inner_dtype: Option<&ArrowDataType>) -> PolarsResult<ListArray<i64>> {105// SAFETY:106// offsets are monotonically increasing107let offsets = unsafe { Offsets::new_unchecked(self.offsets) };108let (inner_dtype, values) = if self.arrays.is_empty() {109let len = *offsets.last() as usize;110match inner_dtype {111None => {112let values = NullArray::new(ArrowDataType::Null, len).boxed();113(ArrowDataType::Null, values)114},115Some(inner_dtype) => {116let values = new_null_array(inner_dtype.clone(), len);117(inner_dtype.clone(), values)118},119}120} else {121let inner_dtype = inner_dtype.unwrap_or_else(|| self.arrays[0].dtype());122123// check if there is a dtype that is not `Null`124// if we find it, we will convert the null arrays125// to empty arrays of this dtype, otherwise the concat kernel fails.126let mut non_null_dtype = None;127if is_nested_null(inner_dtype) {128for arr in &self.arrays {129if !is_nested_null(arr.dtype()) {130non_null_dtype = Some(arr.dtype());131break;132}133}134};135136// there are null arrays found, ensure the types are correct.137if let Some(dtype) = non_null_dtype {138let arrays = self139.arrays140.iter()141.map(|arr| {142if is_nested_null(arr.dtype()) {143convert_inner_type(&**arr, dtype)144} else {145arr.to_boxed()146}147})148.collect::<Vec<_>>();149150let values = concatenate::concatenate_unchecked(&arrays)?;151(dtype.clone(), values)152} else {153let values = concatenate::concatenate(&self.arrays)?;154(inner_dtype.clone(), values)155}156};157let dtype = ListArray::<i64>::default_datatype(inner_dtype);158Ok(ListArray::<i64>::new(159dtype,160offsets.into(),161values,162self.validity163.and_then(|validity| validity.into_opt_validity()),164))165}166}167168169