1use std::{any::Any, sync::Arc};
19
20use crate::{types::RunEndIndexType, ArrayRef, ArrowPrimitiveType, RunArray};
21
22use super::{ArrayBuilder, PrimitiveBuilder};
23
24use arrow_buffer::ArrowNativeType;
25
26#[derive(Debug)]
61pub struct PrimitiveRunBuilder<R, V>
62where
63 R: RunEndIndexType,
64 V: ArrowPrimitiveType,
65{
66 run_ends_builder: PrimitiveBuilder<R>,
67 values_builder: PrimitiveBuilder<V>,
68 current_value: Option<V::Native>,
69 current_run_end_index: usize,
70 prev_run_end_index: usize,
71}
72
73impl<R, V> Default for PrimitiveRunBuilder<R, V>
74where
75 R: RunEndIndexType,
76 V: ArrowPrimitiveType,
77{
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83impl<R, V> PrimitiveRunBuilder<R, V>
84where
85 R: RunEndIndexType,
86 V: ArrowPrimitiveType,
87{
88 pub fn new() -> Self {
90 Self {
91 run_ends_builder: PrimitiveBuilder::new(),
92 values_builder: PrimitiveBuilder::new(),
93 current_value: None,
94 current_run_end_index: 0,
95 prev_run_end_index: 0,
96 }
97 }
98
99 pub fn with_capacity(capacity: usize) -> Self {
103 Self {
104 run_ends_builder: PrimitiveBuilder::with_capacity(capacity),
105 values_builder: PrimitiveBuilder::with_capacity(capacity),
106 current_value: None,
107 current_run_end_index: 0,
108 prev_run_end_index: 0,
109 }
110 }
111}
112
113impl<R, V> ArrayBuilder for PrimitiveRunBuilder<R, V>
114where
115 R: RunEndIndexType,
116 V: ArrowPrimitiveType,
117{
118 fn as_any(&self) -> &dyn Any {
120 self
121 }
122
123 fn as_any_mut(&mut self) -> &mut dyn Any {
125 self
126 }
127
128 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
130 self
131 }
132
133 fn len(&self) -> usize {
136 self.current_run_end_index
137 }
138
139 fn finish(&mut self) -> ArrayRef {
141 Arc::new(self.finish())
142 }
143
144 fn finish_cloned(&self) -> ArrayRef {
146 Arc::new(self.finish_cloned())
147 }
148}
149
150impl<R, V> PrimitiveRunBuilder<R, V>
151where
152 R: RunEndIndexType,
153 V: ArrowPrimitiveType,
154{
155 pub fn append_option(&mut self, value: Option<V::Native>) {
157 if self.current_run_end_index == 0 {
158 self.current_run_end_index = 1;
159 self.current_value = value;
160 return;
161 }
162 if self.current_value != value {
163 self.append_run_end();
164 self.current_value = value;
165 }
166
167 self.current_run_end_index += 1;
168 }
169
170 pub fn append_value(&mut self, value: V::Native) {
172 self.append_option(Some(value))
173 }
174
175 pub fn append_null(&mut self) {
177 self.append_option(None)
178 }
179
180 pub fn finish(&mut self) -> RunArray<R> {
183 self.append_run_end();
185
186 self.current_value = None;
188 self.current_run_end_index = 0;
189
190 let run_ends_array = self.run_ends_builder.finish();
192 let values_array = self.values_builder.finish();
193 RunArray::<R>::try_new(&run_ends_array, &values_array).unwrap()
194 }
195
196 pub fn finish_cloned(&self) -> RunArray<R> {
199 let mut run_ends_array = self.run_ends_builder.finish_cloned();
200 let mut values_array = self.values_builder.finish_cloned();
201
202 if self.prev_run_end_index != self.current_run_end_index {
204 let mut run_end_builder = run_ends_array.into_builder().unwrap();
205 let mut values_builder = values_array.into_builder().unwrap();
206 self.append_run_end_with_builders(&mut run_end_builder, &mut values_builder);
207 run_ends_array = run_end_builder.finish();
208 values_array = values_builder.finish();
209 }
210
211 RunArray::try_new(&run_ends_array, &values_array).unwrap()
212 }
213
214 fn append_run_end(&mut self) {
216 if self.prev_run_end_index == self.current_run_end_index {
218 return;
219 }
220 let run_end_index = self.run_end_index_as_native();
221 self.run_ends_builder.append_value(run_end_index);
222 self.values_builder.append_option(self.current_value);
223 self.prev_run_end_index = self.current_run_end_index;
224 }
225
226 fn append_run_end_with_builders(
229 &self,
230 run_ends_builder: &mut PrimitiveBuilder<R>,
231 values_builder: &mut PrimitiveBuilder<V>,
232 ) {
233 let run_end_index = self.run_end_index_as_native();
234 run_ends_builder.append_value(run_end_index);
235 values_builder.append_option(self.current_value);
236 }
237
238 fn run_end_index_as_native(&self) -> R::Native {
239 R::Native::from_usize(self.current_run_end_index)
240 .unwrap_or_else(|| panic!(
241 "Cannot convert `current_run_end_index` {} from `usize` to native form of arrow datatype {}",
242 self.current_run_end_index,
243 R::DATA_TYPE
244 ))
245 }
246}
247
248impl<R, V> Extend<Option<V::Native>> for PrimitiveRunBuilder<R, V>
249where
250 R: RunEndIndexType,
251 V: ArrowPrimitiveType,
252{
253 fn extend<T: IntoIterator<Item = Option<V::Native>>>(&mut self, iter: T) {
254 for elem in iter {
255 self.append_option(elem);
256 }
257 }
258}
259
260#[cfg(test)]
261mod tests {
262 use crate::builder::PrimitiveRunBuilder;
263 use crate::cast::AsArray;
264 use crate::types::{Int16Type, UInt32Type};
265 use crate::{Array, UInt32Array};
266
267 #[test]
268 fn test_primitive_ree_array_builder() {
269 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::new();
270 builder.append_value(1234);
271 builder.append_value(1234);
272 builder.append_value(1234);
273 builder.append_null();
274 builder.append_value(5678);
275 builder.append_value(5678);
276
277 let array = builder.finish();
278
279 assert_eq!(array.null_count(), 0);
280 assert_eq!(array.logical_null_count(), 1);
281 assert_eq!(array.len(), 6);
282
283 assert_eq!(array.run_ends().values(), &[3, 4, 6]);
284
285 let av = array.values();
286
287 assert!(!av.is_null(0));
288 assert!(av.is_null(1));
289 assert!(!av.is_null(2));
290
291 let ava: &UInt32Array = av.as_primitive::<UInt32Type>();
293
294 assert_eq!(ava, &UInt32Array::from(vec![Some(1234), None, Some(5678)]));
295 }
296
297 #[test]
298 fn test_extend() {
299 let mut builder = PrimitiveRunBuilder::<Int16Type, Int16Type>::new();
300 builder.extend([1, 2, 2, 5, 5, 4, 4].into_iter().map(Some));
301 builder.extend([4, 4, 6, 2].into_iter().map(Some));
302 let array = builder.finish();
303
304 assert_eq!(array.len(), 11);
305 assert_eq!(array.null_count(), 0);
306 assert_eq!(array.logical_null_count(), 0);
307 assert_eq!(array.run_ends().values(), &[1, 3, 5, 9, 10, 11]);
308 assert_eq!(
309 array.values().as_primitive::<Int16Type>().values(),
310 &[1, 2, 5, 4, 6, 2]
311 );
312 }
313}