1use crate::builder::ArrayBuilder;
19use crate::{Array, ArrayRef, MapArray, StructArray};
20use arrow_buffer::Buffer;
21use arrow_buffer::{NullBuffer, NullBufferBuilder};
22use arrow_data::ArrayData;
23use arrow_schema::{ArrowError, DataType, Field, FieldRef};
24use std::any::Any;
25use std::sync::Arc;
26
27#[derive(Debug)]
58pub struct MapBuilder<K: ArrayBuilder, V: ArrayBuilder> {
59 offsets_builder: Vec<i32>,
60 null_buffer_builder: NullBufferBuilder,
61 field_names: MapFieldNames,
62 key_builder: K,
63 value_builder: V,
64 key_field: Option<FieldRef>,
65 value_field: Option<FieldRef>,
66}
67
68#[derive(Debug, Clone)]
70pub struct MapFieldNames {
71 pub entry: String,
73 pub key: String,
75 pub value: String,
77}
78
79impl Default for MapFieldNames {
80 fn default() -> Self {
81 Self {
82 entry: Field::MAP_ENTRIES_FIELD_DEFAULT_NAME.to_string(),
83 key: Field::MAP_KEY_FIELD_DEFAULT_NAME.to_string(),
84 value: Field::MAP_VALUE_FIELD_DEFAULT_NAME.to_string(),
85 }
86 }
87}
88
89impl<K: ArrayBuilder, V: ArrayBuilder> MapBuilder<K, V> {
90 pub fn new(field_names: Option<MapFieldNames>, key_builder: K, value_builder: V) -> Self {
92 let capacity = key_builder.len();
93 Self::with_capacity(field_names, key_builder, value_builder, capacity)
94 }
95
96 pub fn with_capacity(
98 field_names: Option<MapFieldNames>,
99 key_builder: K,
100 value_builder: V,
101 capacity: usize,
102 ) -> Self {
103 let mut offsets_builder = Vec::with_capacity(capacity + 1);
104 offsets_builder.push(0);
105 Self {
106 offsets_builder,
107 null_buffer_builder: NullBufferBuilder::new(capacity),
108 field_names: field_names.unwrap_or_default(),
109 key_builder,
110 value_builder,
111 key_field: None,
112 value_field: None,
113 }
114 }
115
116 pub fn with_keys_field(self, field: impl Into<FieldRef>) -> Self {
123 Self {
124 key_field: Some(field.into()),
125 ..self
126 }
127 }
128
129 pub fn with_values_field(self, field: impl Into<FieldRef>) -> Self {
136 Self {
137 value_field: Some(field.into()),
138 ..self
139 }
140 }
141
142 pub fn keys(&mut self) -> &mut K {
144 &mut self.key_builder
145 }
146
147 pub fn values(&mut self) -> &mut V {
149 &mut self.value_builder
150 }
151
152 pub fn entries(&mut self) -> (&mut K, &mut V) {
154 (&mut self.key_builder, &mut self.value_builder)
155 }
156
157 #[inline]
159 fn validate_equal_lengths(&self) -> Result<(), ArrowError> {
160 if self.key_builder.len() != self.value_builder.len() {
161 return Err(ArrowError::InvalidArgumentError(format!(
162 "Cannot append to a map builder when its keys and values have unequal lengths of {} and {}",
163 self.key_builder.len(),
164 self.value_builder.len()
165 )));
166 }
167 Ok(())
168 }
169
170 #[inline]
174 pub fn append(&mut self, is_valid: bool) -> Result<(), ArrowError> {
175 self.validate_equal_lengths()?;
176 self.offsets_builder.push(self.key_builder.len() as i32);
177 self.null_buffer_builder.append(is_valid);
178 Ok(())
179 }
180
181 #[inline]
185 pub fn append_nulls(&mut self, n: usize) -> Result<(), ArrowError> {
186 self.validate_equal_lengths()?;
187 let offset = self.key_builder.len() as i32;
188 self.offsets_builder.extend(std::iter::repeat_n(offset, n));
189 self.null_buffer_builder.append_n_nulls(n);
190 Ok(())
191 }
192
193 pub fn finish(&mut self) -> MapArray {
201 let len = self.len();
202 let keys_arr = self.key_builder.finish();
204 let values_arr = self.value_builder.finish();
205 let offset_buffer = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
206 self.offsets_builder.push(0);
207 let null_bit_buffer = self.null_buffer_builder.finish();
208
209 self.finish_helper(keys_arr, values_arr, offset_buffer, null_bit_buffer, len)
210 }
211
212 pub fn finish_cloned(&self) -> MapArray {
220 let len = self.len();
221 let keys_arr = self.key_builder.finish_cloned();
223 let values_arr = self.value_builder.finish_cloned();
224 let offset_buffer = Buffer::from_slice_ref(self.offsets_builder.as_slice());
225 let nulls = self.null_buffer_builder.finish_cloned();
226 self.finish_helper(keys_arr, values_arr, offset_buffer, nulls, len)
227 }
228
229 fn finish_preserve_values(&mut self) -> MapArray {
230 let len = self.len();
231 let keys_arr = self.key_builder.finish_preserve_values();
233 let values_arr = self.value_builder.finish_preserve_values();
234 let offset_buffer = Buffer::from_vec(std::mem::take(&mut self.offsets_builder));
235 self.offsets_builder.push(0);
236 let null_bit_buffer = self.null_buffer_builder.finish();
237
238 self.finish_helper(keys_arr, values_arr, offset_buffer, null_bit_buffer, len)
239 }
240
241 fn finish_helper(
242 &self,
243 keys_arr: Arc<dyn Array>,
244 values_arr: Arc<dyn Array>,
245 offset_buffer: Buffer,
246 nulls: Option<NullBuffer>,
247 len: usize,
248 ) -> MapArray {
249 assert!(
250 keys_arr.null_count() == 0,
251 "Keys array must have no null values, found {} null value(s)",
252 keys_arr.null_count()
253 );
254
255 let keys_field = match &self.key_field {
256 Some(f) => {
257 assert!(!f.is_nullable(), "Keys field must not be nullable");
258 f.clone()
259 }
260 None => Arc::new(Field::new(
261 self.field_names.key.as_str(),
262 keys_arr.data_type().clone(),
263 false, )),
265 };
266 let values_field = match &self.value_field {
267 Some(f) => f.clone(),
268 None => Arc::new(Field::new(
269 self.field_names.value.as_str(),
270 values_arr.data_type().clone(),
271 true,
272 )),
273 };
274
275 let struct_array =
276 StructArray::from(vec![(keys_field, keys_arr), (values_field, values_arr)]);
277
278 let map_field = Arc::new(Field::new(
279 self.field_names.entry.as_str(),
280 struct_array.data_type().clone(),
281 false, ));
283 let array_data = ArrayData::builder(DataType::Map(map_field, false)) .len(len)
285 .add_buffer(offset_buffer)
286 .add_child_data(struct_array.into_data())
287 .nulls(nulls);
288
289 let array_data = unsafe { array_data.build_unchecked() };
290
291 MapArray::from(array_data)
292 }
293
294 pub fn validity_slice(&self) -> Option<&[u8]> {
296 self.null_buffer_builder.as_slice()
297 }
298}
299
300impl<K: ArrayBuilder, V: ArrayBuilder> ArrayBuilder for MapBuilder<K, V> {
301 fn len(&self) -> usize {
302 self.null_buffer_builder.len()
303 }
304
305 fn finish(&mut self) -> ArrayRef {
306 Arc::new(self.finish())
307 }
308
309 fn finish_cloned(&self) -> ArrayRef {
311 Arc::new(self.finish_cloned())
312 }
313
314 fn finish_preserve_values(&mut self) -> ArrayRef {
315 Arc::new(self.finish_preserve_values())
316 }
317
318 fn as_any(&self) -> &dyn Any {
319 self
320 }
321
322 fn as_any_mut(&mut self) -> &mut dyn Any {
323 self
324 }
325
326 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
327 self
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 use super::*;
334 use crate::builder::{Int32Builder, StringBuilder, make_builder, tests::PreserveValuesMock};
335 use crate::{Int32Array, StringArray};
336 use std::collections::HashMap;
337
338 #[test]
339 #[should_panic(expected = "Keys array must have no null values, found 1 null value(s)")]
340 fn test_map_builder_with_null_keys_panics() {
341 let mut builder = MapBuilder::new(None, StringBuilder::new(), Int32Builder::new());
342 builder.keys().append_null();
343 builder.values().append_value(42);
344 builder.append(true).unwrap();
345
346 builder.finish();
347 }
348
349 #[test]
350 fn test_boxed_map_builder() {
351 let keys_builder = make_builder(&DataType::Utf8, 5);
352 let values_builder = make_builder(&DataType::Int32, 5);
353
354 let mut builder = MapBuilder::new(None, keys_builder, values_builder);
355 builder
356 .keys()
357 .as_any_mut()
358 .downcast_mut::<StringBuilder>()
359 .expect("should be an StringBuilder")
360 .append_value("1");
361 builder
362 .values()
363 .as_any_mut()
364 .downcast_mut::<Int32Builder>()
365 .expect("should be an Int32Builder")
366 .append_value(42);
367 builder.append(true).unwrap();
368
369 let map_array = builder.finish();
370
371 assert_eq!(
372 map_array
373 .keys()
374 .as_any()
375 .downcast_ref::<StringArray>()
376 .expect("should be an StringArray")
377 .value(0),
378 "1"
379 );
380 assert_eq!(
381 map_array
382 .values()
383 .as_any()
384 .downcast_ref::<Int32Array>()
385 .expect("should be an Int32Array")
386 .value(0),
387 42
388 );
389 }
390
391 #[test]
392 fn test_with_values_field() {
393 let value_field = Arc::new(Field::new("bars", DataType::Int32, false));
394 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
395 .with_values_field(value_field.clone());
396 builder.keys().append_value(1);
397 builder.values().append_value(2);
398 builder.append(true).unwrap();
399 builder.append(false).unwrap(); builder.keys().append_value(3);
401 builder.values().append_value(4);
402 builder.append(true).unwrap();
403 let map = builder.finish();
404
405 assert_eq!(map.len(), 3);
406 assert_eq!(
407 map.data_type(),
408 &DataType::Map(
409 Arc::new(Field::new(
410 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
411 DataType::Struct(
412 vec![
413 Arc::new(Field::new(
414 Field::MAP_KEY_FIELD_DEFAULT_NAME,
415 DataType::Int32,
416 false
417 )),
418 value_field.clone()
419 ]
420 .into()
421 ),
422 false,
423 )),
424 false
425 )
426 );
427
428 builder.keys().append_value(5);
429 builder.values().append_value(6);
430 builder.append(true).unwrap();
431 let map = builder.finish();
432
433 assert_eq!(map.len(), 1);
434 assert_eq!(
435 map.data_type(),
436 &DataType::Map(
437 Arc::new(Field::new(
438 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
439 DataType::Struct(
440 vec![
441 Arc::new(Field::new(
442 Field::MAP_KEY_FIELD_DEFAULT_NAME,
443 DataType::Int32,
444 false
445 )),
446 value_field
447 ]
448 .into()
449 ),
450 false,
451 )),
452 false
453 )
454 );
455 }
456
457 #[test]
458 fn test_with_keys_field() {
459 let mut key_metadata = HashMap::new();
460 key_metadata.insert("foo".to_string(), "bar".to_string());
461 let key_field = Arc::new(
462 Field::new("other_key", DataType::Int32, false).with_metadata(key_metadata.clone()),
463 );
464 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
465 .with_keys_field(key_field.clone());
466 builder.keys().append_value(1);
467 builder.values().append_value(2);
468 builder.append(true).unwrap();
469 let map = builder.finish();
470
471 assert_eq!(map.len(), 1);
472 assert_eq!(
473 map.data_type(),
474 &DataType::Map(
475 Arc::new(Field::new(
476 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
477 DataType::Struct(
478 vec![
479 Arc::new(
480 Field::new("other_key", DataType::Int32, false)
481 .with_metadata(key_metadata)
482 ),
483 Arc::new(Field::new(
484 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
485 DataType::Int32,
486 true
487 ))
488 ]
489 .into()
490 ),
491 false,
492 )),
493 false
494 )
495 );
496 }
497
498 #[test]
499 fn test_append_nulls() {
500 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new());
501
502 builder.keys().append_value(1);
503 builder.values().append_value(100);
504 builder.append(true).unwrap();
505
506 builder.append_nulls(3).unwrap();
507
508 builder.keys().append_value(2);
509 builder.values().append_value(200);
510 builder.append(true).unwrap();
511
512 let map = builder.finish();
513 assert_eq!(map.len(), 5);
514 assert_eq!(map.null_count(), 3);
515 assert!(map.is_valid(0));
516 assert!(map.is_null(1));
517 assert!(map.is_null(2));
518 assert!(map.is_null(3));
519 assert!(map.is_valid(4));
520 assert_eq!(map.value_offsets(), &[0, 1, 1, 1, 1, 2]);
521 }
522
523 #[test]
524 fn test_append_nulls_inconsistent_state() {
525 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new());
526 builder.keys().append_value(1);
528
529 let result = builder.append_nulls(2);
530 assert!(result.is_err());
531 assert!(result.unwrap_err().to_string().contains("unequal lengths"));
532 }
533
534 #[test]
535 #[should_panic(expected = "Keys field must not be nullable")]
536 fn test_with_nullable_keys_field() {
537 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
538 .with_keys_field(Arc::new(Field::new(
539 Field::MAP_KEY_FIELD_DEFAULT_NAME,
540 DataType::Int32,
541 true,
542 )));
543
544 builder.keys().append_value(1);
545 builder.values().append_value(2);
546 builder.append(true).unwrap();
547
548 builder.finish();
549 }
550
551 #[test]
552 #[should_panic(expected = "Incorrect datatype")]
553 fn test_keys_field_type_mismatch() {
554 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
555 .with_keys_field(Arc::new(Field::new(
556 Field::MAP_KEY_FIELD_DEFAULT_NAME,
557 DataType::Utf8,
558 false,
559 )));
560
561 builder.keys().append_value(1);
562 builder.values().append_value(2);
563 builder.append(true).unwrap();
564
565 builder.finish();
566 }
567
568 #[test]
569 fn test_finish_preserve_values() {
570 let mut builder = MapBuilder::new(
571 None,
572 PreserveValuesMock::default(),
573 PreserveValuesMock::default(),
574 );
575
576 builder.keys().inner.append_value(1);
577 builder.values().inner.append_value(2);
578 builder.append(true).unwrap();
579
580 let map = builder.finish_preserve_values();
581
582 assert_eq!(1, map.len());
583 assert_eq!(1, builder.keys().called);
584 assert_eq!(1, builder.values().called);
585 }
586}