arrow2/array/fixed_size_list/
mutable.rs1use std::sync::Arc;
2
3use crate::array::PushUnchecked;
4use crate::{
5 array::{
6 physical_binary::extend_validity, Array, MutableArray, TryExtend, TryExtendFromSelf,
7 TryPush,
8 },
9 bitmap::MutableBitmap,
10 datatypes::{DataType, Field},
11 error::{Error, Result},
12};
13
14use super::FixedSizeListArray;
15
16#[derive(Debug, Clone)]
18pub struct MutableFixedSizeListArray<M: MutableArray> {
19 data_type: DataType,
20 size: usize,
21 values: M,
22 validity: Option<MutableBitmap>,
23}
24
25impl<M: MutableArray> From<MutableFixedSizeListArray<M>> for FixedSizeListArray {
26 fn from(mut other: MutableFixedSizeListArray<M>) -> Self {
27 FixedSizeListArray::new(
28 other.data_type,
29 other.values.as_box(),
30 other.validity.map(|x| x.into()),
31 )
32 }
33}
34
35impl<M: MutableArray> MutableFixedSizeListArray<M> {
36 pub fn new(values: M, size: usize) -> Self {
38 let data_type = FixedSizeListArray::default_datatype(values.data_type().clone(), size);
39 Self::new_from(values, data_type, size)
40 }
41
42 pub fn new_with_field(values: M, name: &str, nullable: bool, size: usize) -> Self {
44 let data_type = DataType::FixedSizeList(
45 Box::new(Field::new(name, values.data_type().clone(), nullable)),
46 size,
47 );
48 Self::new_from(values, data_type, size)
49 }
50
51 pub fn new_from(values: M, data_type: DataType, size: usize) -> Self {
53 assert_eq!(values.len(), 0);
54 match data_type {
55 DataType::FixedSizeList(..) => (),
56 _ => panic!("data type must be FixedSizeList (got {data_type:?})"),
57 };
58 Self {
59 size,
60 data_type,
61 values,
62 validity: None,
63 }
64 }
65
66 pub const fn size(&self) -> usize {
68 self.size
69 }
70
71 pub fn len(&self) -> usize {
73 self.values.len() / self.size
74 }
75
76 pub fn values(&self) -> &M {
78 &self.values
79 }
80
81 pub fn mut_values(&mut self) -> &mut M {
83 &mut self.values
84 }
85
86 fn init_validity(&mut self) {
87 let len = self.values.len() / self.size;
88
89 let mut validity = MutableBitmap::new();
90 validity.extend_constant(len, true);
91 validity.set(len - 1, false);
92 self.validity = Some(validity)
93 }
94
95 #[inline]
96 pub fn try_push_valid(&mut self) -> Result<()> {
99 if self.values.len() % self.size != 0 {
100 return Err(Error::Overflow);
101 };
102 if let Some(validity) = &mut self.validity {
103 validity.push(true)
104 }
105 Ok(())
106 }
107
108 #[inline]
109 pub fn push_valid(&mut self) {
112 if let Some(validity) = &mut self.validity {
113 validity.push(true)
114 }
115 }
116
117 #[inline]
118 fn push_null(&mut self) {
119 (0..self.size).for_each(|_| self.values.push_null());
120 match &mut self.validity {
121 Some(validity) => validity.push(false),
122 None => self.init_validity(),
123 }
124 }
125
126 pub fn reserve(&mut self, additional: usize) {
128 self.values.reserve(additional);
129 if let Some(x) = self.validity.as_mut() {
130 x.reserve(additional)
131 }
132 }
133
134 pub fn shrink_to_fit(&mut self) {
136 self.values.shrink_to_fit();
137 if let Some(validity) = &mut self.validity {
138 validity.shrink_to_fit()
139 }
140 }
141}
142
143impl<M: MutableArray + 'static> MutableArray for MutableFixedSizeListArray<M> {
144 fn len(&self) -> usize {
145 self.values.len() / self.size
146 }
147
148 fn validity(&self) -> Option<&MutableBitmap> {
149 self.validity.as_ref()
150 }
151
152 fn as_box(&mut self) -> Box<dyn Array> {
153 FixedSizeListArray::new(
154 self.data_type.clone(),
155 self.values.as_box(),
156 std::mem::take(&mut self.validity).map(|x| x.into()),
157 )
158 .boxed()
159 }
160
161 fn as_arc(&mut self) -> Arc<dyn Array> {
162 FixedSizeListArray::new(
163 self.data_type.clone(),
164 self.values.as_box(),
165 std::mem::take(&mut self.validity).map(|x| x.into()),
166 )
167 .arced()
168 }
169
170 fn data_type(&self) -> &DataType {
171 &self.data_type
172 }
173
174 fn as_any(&self) -> &dyn std::any::Any {
175 self
176 }
177
178 fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
179 self
180 }
181
182 #[inline]
183 fn push_null(&mut self) {
184 (0..self.size).for_each(|_| {
185 self.values.push_null();
186 });
187 if let Some(validity) = &mut self.validity {
188 validity.push(false)
189 } else {
190 self.init_validity()
191 }
192 }
193
194 fn reserve(&mut self, additional: usize) {
195 self.reserve(additional)
196 }
197
198 fn shrink_to_fit(&mut self) {
199 self.shrink_to_fit()
200 }
201}
202
203impl<M, I, T> TryExtend<Option<I>> for MutableFixedSizeListArray<M>
204where
205 M: MutableArray + TryExtend<Option<T>>,
206 I: IntoIterator<Item = Option<T>>,
207{
208 #[inline]
209 fn try_extend<II: IntoIterator<Item = Option<I>>>(&mut self, iter: II) -> Result<()> {
210 for items in iter {
211 self.try_push(items)?;
212 }
213 Ok(())
214 }
215}
216
217impl<M, I, T> TryPush<Option<I>> for MutableFixedSizeListArray<M>
218where
219 M: MutableArray + TryExtend<Option<T>>,
220 I: IntoIterator<Item = Option<T>>,
221{
222 #[inline]
223 fn try_push(&mut self, item: Option<I>) -> Result<()> {
224 if let Some(items) = item {
225 self.values.try_extend(items)?;
226 self.try_push_valid()?;
227 } else {
228 self.push_null();
229 }
230 Ok(())
231 }
232}
233
234impl<M, I, T> PushUnchecked<Option<I>> for MutableFixedSizeListArray<M>
235where
236 M: MutableArray + Extend<Option<T>>,
237 I: IntoIterator<Item = Option<T>>,
238{
239 #[inline]
243 unsafe fn push_unchecked(&mut self, item: Option<I>) {
244 if let Some(items) = item {
245 self.values.extend(items);
246 self.push_valid();
247 } else {
248 self.push_null();
249 }
250 }
251}
252
253impl<M> TryExtendFromSelf for MutableFixedSizeListArray<M>
254where
255 M: MutableArray + TryExtendFromSelf,
256{
257 fn try_extend_from_self(&mut self, other: &Self) -> Result<()> {
258 extend_validity(self.len(), &mut self.validity, &other.validity);
259
260 self.values.try_extend_from_self(&other.values)
261 }
262}