1use std::sync::Arc;
2
3use polars_error::{polars_err, PolarsResult};
4use polars_utils::pl_str::PlSmallStr;
5
6use super::ListArray;
7use crate::array::physical_binary::extend_validity;
8use crate::array::{Array, MutableArray, TryExtend, TryExtendFromSelf, TryPush};
9use crate::bitmap::MutableBitmap;
10use crate::datatypes::{ArrowDataType, Field};
11use crate::offset::{Offset, Offsets};
12use crate::trusted_len::TrustedLen;
13
14#[derive(Debug, Clone)]
16pub struct MutableListArray<O: Offset, M: MutableArray> {
17 dtype: ArrowDataType,
18 offsets: Offsets<O>,
19 values: M,
20 validity: Option<MutableBitmap>,
21}
22
23impl<O: Offset, M: MutableArray + Default> MutableListArray<O, M> {
24 pub fn new() -> Self {
26 let values = M::default();
27 let dtype = ListArray::<O>::default_datatype(values.dtype().clone());
28 Self::new_from(values, dtype, 0)
29 }
30
31 pub fn with_capacity(capacity: usize) -> Self {
33 let values = M::default();
34 let dtype = ListArray::<O>::default_datatype(values.dtype().clone());
35
36 let offsets = Offsets::<O>::with_capacity(capacity);
37 Self {
38 dtype,
39 offsets,
40 values,
41 validity: None,
42 }
43 }
44}
45
46impl<O: Offset, M: MutableArray + Default> Default for MutableListArray<O, M> {
47 fn default() -> Self {
48 Self::new()
49 }
50}
51
52impl<O: Offset, M: MutableArray> From<MutableListArray<O, M>> for ListArray<O> {
53 fn from(mut other: MutableListArray<O, M>) -> Self {
54 ListArray::new(
55 other.dtype,
56 other.offsets.into(),
57 other.values.as_box(),
58 other.validity.map(|x| x.into()),
59 )
60 }
61}
62
63impl<O, M, I, T> TryExtend<Option<I>> for MutableListArray<O, M>
64where
65 O: Offset,
66 M: MutableArray + TryExtend<Option<T>>,
67 I: IntoIterator<Item = Option<T>>,
68{
69 fn try_extend<II: IntoIterator<Item = Option<I>>>(&mut self, iter: II) -> PolarsResult<()> {
70 let iter = iter.into_iter();
71 self.reserve(iter.size_hint().0);
72 for items in iter {
73 self.try_push(items)?;
74 }
75 Ok(())
76 }
77}
78
79impl<O, M, I, T> TryPush<Option<I>> for MutableListArray<O, M>
80where
81 O: Offset,
82 M: MutableArray + TryExtend<Option<T>>,
83 I: IntoIterator<Item = Option<T>>,
84{
85 #[inline]
86 fn try_push(&mut self, item: Option<I>) -> PolarsResult<()> {
87 if let Some(items) = item {
88 let values = self.mut_values();
89 values.try_extend(items)?;
90 self.try_push_valid()?;
91 } else {
92 self.push_null();
93 }
94 Ok(())
95 }
96}
97
98impl<O, M> TryExtendFromSelf for MutableListArray<O, M>
99where
100 O: Offset,
101 M: MutableArray + TryExtendFromSelf,
102{
103 fn try_extend_from_self(&mut self, other: &Self) -> PolarsResult<()> {
104 extend_validity(self.len(), &mut self.validity, &other.validity);
105
106 self.values.try_extend_from_self(&other.values)?;
107 self.offsets.try_extend_from_self(&other.offsets)
108 }
109}
110
111impl<O: Offset, M: MutableArray> MutableListArray<O, M> {
112 pub fn new_from(values: M, dtype: ArrowDataType, capacity: usize) -> Self {
114 let offsets = Offsets::<O>::with_capacity(capacity);
115 assert_eq!(values.len(), 0);
116 ListArray::<O>::get_child_field(&dtype);
117 Self {
118 dtype,
119 offsets,
120 values,
121 validity: None,
122 }
123 }
124
125 pub fn new_with_field(values: M, name: PlSmallStr, nullable: bool) -> Self {
127 let field = Box::new(Field::new(name, values.dtype().clone(), nullable));
128 let dtype = if O::IS_LARGE {
129 ArrowDataType::LargeList(field)
130 } else {
131 ArrowDataType::List(field)
132 };
133 Self::new_from(values, dtype, 0)
134 }
135
136 pub fn new_with_capacity(values: M, capacity: usize) -> Self {
138 let dtype = ListArray::<O>::default_datatype(values.dtype().clone());
139 Self::new_from(values, dtype, capacity)
140 }
141
142 pub fn new_from_mutable(
145 values: M,
146 offsets: Offsets<O>,
147 validity: Option<MutableBitmap>,
148 ) -> Self {
149 assert_eq!(values.len(), offsets.last().to_usize());
150 let dtype = ListArray::<O>::default_datatype(values.dtype().clone());
151 Self {
152 dtype,
153 offsets,
154 values,
155 validity,
156 }
157 }
158
159 #[inline]
160 pub fn try_push_valid(&mut self) -> PolarsResult<()> {
163 let total_length = self.values.len();
164 let offset = self.offsets.last().to_usize();
165 let length = total_length
166 .checked_sub(offset)
167 .ok_or_else(|| polars_err!(ComputeError: "overflow"))?;
168
169 self.offsets.try_push(length)?;
170 if let Some(validity) = &mut self.validity {
171 validity.push(true)
172 }
173 Ok(())
174 }
175
176 #[inline]
177 fn push_null(&mut self) {
178 self.offsets.extend_constant(1);
179 match &mut self.validity {
180 Some(validity) => validity.push(false),
181 None => self.init_validity(),
182 }
183 }
184
185 pub fn try_extend_from_lengths<II>(&mut self, iterator: II) -> PolarsResult<()>
194 where
195 II: TrustedLen<Item = Option<usize>> + Clone,
196 {
197 self.offsets
198 .try_extend_from_lengths(iterator.clone().map(|x| x.unwrap_or_default()))?;
199 if let Some(validity) = &mut self.validity {
200 validity.extend_from_trusted_len_iter(iterator.map(|x| x.is_some()))
201 }
202 assert_eq!(self.offsets.last().to_usize(), self.values.len());
203 Ok(())
204 }
205
206 #[inline]
208 pub fn len(&self) -> usize {
209 self.offsets.len_proxy()
210 }
211
212 pub fn mut_values(&mut self) -> &mut M {
214 &mut self.values
215 }
216
217 pub fn offsets(&self) -> &Offsets<O> {
219 &self.offsets
220 }
221
222 pub fn values(&self) -> &M {
224 &self.values
225 }
226
227 fn init_validity(&mut self) {
228 let len = self.offsets.len_proxy();
229
230 let mut validity = MutableBitmap::with_capacity(self.offsets.capacity());
231 validity.extend_constant(len, true);
232 validity.set(len - 1, false);
233 self.validity = Some(validity)
234 }
235
236 pub fn into_arc(self) -> Arc<dyn Array> {
238 let a: ListArray<O> = self.into();
239 Arc::new(a)
240 }
241
242 pub fn into_box(self) -> Box<dyn Array> {
244 let a: ListArray<O> = self.into();
245 Box::new(a)
246 }
247
248 pub fn reserve(&mut self, additional: usize) {
250 self.offsets.reserve(additional);
251 if let Some(x) = self.validity.as_mut() {
252 x.reserve(additional)
253 }
254 }
255
256 pub fn shrink_to_fit(&mut self) {
258 self.values.shrink_to_fit();
259 self.offsets.shrink_to_fit();
260 if let Some(validity) = &mut self.validity {
261 validity.shrink_to_fit()
262 }
263 }
264}
265
266impl<O: Offset, M: MutableArray + 'static> MutableArray for MutableListArray<O, M> {
267 fn len(&self) -> usize {
268 MutableListArray::len(self)
269 }
270
271 fn validity(&self) -> Option<&MutableBitmap> {
272 self.validity.as_ref()
273 }
274
275 fn as_box(&mut self) -> Box<dyn Array> {
276 ListArray::new(
277 self.dtype.clone(),
278 std::mem::take(&mut self.offsets).into(),
279 self.values.as_box(),
280 std::mem::take(&mut self.validity).map(|x| x.into()),
281 )
282 .boxed()
283 }
284
285 fn as_arc(&mut self) -> Arc<dyn Array> {
286 ListArray::new(
287 self.dtype.clone(),
288 std::mem::take(&mut self.offsets).into(),
289 self.values.as_box(),
290 std::mem::take(&mut self.validity).map(|x| x.into()),
291 )
292 .arced()
293 }
294
295 fn dtype(&self) -> &ArrowDataType {
296 &self.dtype
297 }
298
299 fn as_any(&self) -> &dyn std::any::Any {
300 self
301 }
302
303 fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
304 self
305 }
306
307 #[inline]
308 fn push_null(&mut self) {
309 self.push_null()
310 }
311
312 fn reserve(&mut self, additional: usize) {
313 self.reserve(additional)
314 }
315
316 fn shrink_to_fit(&mut self) {
317 self.shrink_to_fit();
318 }
319}