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() };
291
292 MapArray::from(array_data)
293 }
294
295 pub fn validity_slice(&self) -> Option<&[u8]> {
297 self.null_buffer_builder.as_slice()
298 }
299}
300
301impl<K: ArrayBuilder, V: ArrayBuilder> ArrayBuilder for MapBuilder<K, V> {
302 fn len(&self) -> usize {
303 self.null_buffer_builder.len()
304 }
305
306 fn finish(&mut self) -> ArrayRef {
307 Arc::new(self.finish())
308 }
309
310 fn finish_cloned(&self) -> ArrayRef {
312 Arc::new(self.finish_cloned())
313 }
314
315 fn finish_preserve_values(&mut self) -> ArrayRef {
316 Arc::new(self.finish_preserve_values())
317 }
318
319 fn as_any(&self) -> &dyn Any {
320 self
321 }
322
323 fn as_any_mut(&mut self) -> &mut dyn Any {
324 self
325 }
326
327 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
328 self
329 }
330}
331
332#[cfg(test)]
333mod tests {
334 use super::*;
335 use crate::builder::{Int32Builder, StringBuilder, make_builder, tests::PreserveValuesMock};
336 use crate::{Int32Array, StringArray};
337 use std::collections::HashMap;
338
339 #[test]
340 #[should_panic(expected = "Keys array must have no null values, found 1 null value(s)")]
341 fn test_map_builder_with_null_keys_panics() {
342 let mut builder = MapBuilder::new(None, StringBuilder::new(), Int32Builder::new());
343 builder.keys().append_null();
344 builder.values().append_value(42);
345 builder.append(true).unwrap();
346
347 builder.finish();
348 }
349
350 #[test]
351 fn test_boxed_map_builder() {
352 let keys_builder = make_builder(&DataType::Utf8, 5);
353 let values_builder = make_builder(&DataType::Int32, 5);
354
355 let mut builder = MapBuilder::new(None, keys_builder, values_builder);
356 builder
357 .keys()
358 .as_any_mut()
359 .downcast_mut::<StringBuilder>()
360 .expect("should be an StringBuilder")
361 .append_value("1");
362 builder
363 .values()
364 .as_any_mut()
365 .downcast_mut::<Int32Builder>()
366 .expect("should be an Int32Builder")
367 .append_value(42);
368 builder.append(true).unwrap();
369
370 let map_array = builder.finish();
371
372 assert_eq!(
373 map_array
374 .keys()
375 .as_any()
376 .downcast_ref::<StringArray>()
377 .expect("should be an StringArray")
378 .value(0),
379 "1"
380 );
381 assert_eq!(
382 map_array
383 .values()
384 .as_any()
385 .downcast_ref::<Int32Array>()
386 .expect("should be an Int32Array")
387 .value(0),
388 42
389 );
390 }
391
392 #[test]
393 fn test_with_values_field() {
394 let value_field = Arc::new(Field::new("bars", DataType::Int32, false));
395 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
396 .with_values_field(value_field.clone());
397 builder.keys().append_value(1);
398 builder.values().append_value(2);
399 builder.append(true).unwrap();
400 builder.append(false).unwrap(); builder.keys().append_value(3);
402 builder.values().append_value(4);
403 builder.append(true).unwrap();
404 let map = builder.finish();
405
406 assert_eq!(map.len(), 3);
407 assert_eq!(
408 map.data_type(),
409 &DataType::Map(
410 Arc::new(Field::new(
411 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
412 DataType::Struct(
413 vec![
414 Arc::new(Field::new(
415 Field::MAP_KEY_FIELD_DEFAULT_NAME,
416 DataType::Int32,
417 false
418 )),
419 value_field.clone()
420 ]
421 .into()
422 ),
423 false,
424 )),
425 false
426 )
427 );
428
429 builder.keys().append_value(5);
430 builder.values().append_value(6);
431 builder.append(true).unwrap();
432 let map = builder.finish();
433
434 assert_eq!(map.len(), 1);
435 assert_eq!(
436 map.data_type(),
437 &DataType::Map(
438 Arc::new(Field::new(
439 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
440 DataType::Struct(
441 vec![
442 Arc::new(Field::new(
443 Field::MAP_KEY_FIELD_DEFAULT_NAME,
444 DataType::Int32,
445 false
446 )),
447 value_field
448 ]
449 .into()
450 ),
451 false,
452 )),
453 false
454 )
455 );
456 }
457
458 #[test]
459 fn test_with_keys_field() {
460 let mut key_metadata = HashMap::new();
461 key_metadata.insert("foo".to_string(), "bar".to_string());
462 let key_field = Arc::new(
463 Field::new("other_key", DataType::Int32, false).with_metadata(key_metadata.clone()),
464 );
465 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
466 .with_keys_field(key_field.clone());
467 builder.keys().append_value(1);
468 builder.values().append_value(2);
469 builder.append(true).unwrap();
470 let map = builder.finish();
471
472 assert_eq!(map.len(), 1);
473 assert_eq!(
474 map.data_type(),
475 &DataType::Map(
476 Arc::new(Field::new(
477 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
478 DataType::Struct(
479 vec![
480 Arc::new(
481 Field::new("other_key", DataType::Int32, false)
482 .with_metadata(key_metadata)
483 ),
484 Arc::new(Field::new(
485 Field::MAP_VALUE_FIELD_DEFAULT_NAME,
486 DataType::Int32,
487 true
488 ))
489 ]
490 .into()
491 ),
492 false,
493 )),
494 false
495 )
496 );
497 }
498
499 #[test]
500 fn test_append_nulls() {
501 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new());
502
503 builder.keys().append_value(1);
504 builder.values().append_value(100);
505 builder.append(true).unwrap();
506
507 builder.append_nulls(3).unwrap();
508
509 builder.keys().append_value(2);
510 builder.values().append_value(200);
511 builder.append(true).unwrap();
512
513 let map = builder.finish();
514 assert_eq!(map.len(), 5);
515 assert_eq!(map.null_count(), 3);
516 assert!(map.is_valid(0));
517 assert!(map.is_null(1));
518 assert!(map.is_null(2));
519 assert!(map.is_null(3));
520 assert!(map.is_valid(4));
521 assert_eq!(map.value_offsets(), &[0, 1, 1, 1, 1, 2]);
522 }
523
524 #[test]
525 fn test_append_nulls_inconsistent_state() {
526 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new());
527 builder.keys().append_value(1);
529
530 let result = builder.append_nulls(2);
531 assert!(result.is_err());
532 assert!(result.unwrap_err().to_string().contains("unequal lengths"));
533 }
534
535 #[test]
536 #[should_panic(expected = "Keys field must not be nullable")]
537 fn test_with_nullable_keys_field() {
538 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
539 .with_keys_field(Arc::new(Field::new(
540 Field::MAP_KEY_FIELD_DEFAULT_NAME,
541 DataType::Int32,
542 true,
543 )));
544
545 builder.keys().append_value(1);
546 builder.values().append_value(2);
547 builder.append(true).unwrap();
548
549 builder.finish();
550 }
551
552 #[test]
553 #[should_panic(expected = "Incorrect datatype")]
554 fn test_keys_field_type_mismatch() {
555 let mut builder = MapBuilder::new(None, Int32Builder::new(), Int32Builder::new())
556 .with_keys_field(Arc::new(Field::new(
557 Field::MAP_KEY_FIELD_DEFAULT_NAME,
558 DataType::Utf8,
559 false,
560 )));
561
562 builder.keys().append_value(1);
563 builder.values().append_value(2);
564 builder.append(true).unwrap();
565
566 builder.finish();
567 }
568
569 #[test]
570 fn test_finish_preserve_values() {
571 let mut builder = MapBuilder::new(
572 None,
573 PreserveValuesMock::default(),
574 PreserveValuesMock::default(),
575 );
576
577 builder.keys().inner.append_value(1);
578 builder.values().inner.append_value(2);
579 builder.append(true).unwrap();
580
581 let map = builder.finish_preserve_values();
582
583 assert_eq!(1, map.len());
584 assert_eq!(1, builder.keys().called);
585 assert_eq!(1, builder.values().called);
586 }
587}