From 5014746ba4bc760e0ddfee1f8f665e855137d025 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Thu, 15 Jan 2026 08:08:32 -0500 Subject: [PATCH] Avoid a clone when creating `MapArray` from ArrayData --- arrow-array/src/array/map_array.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/arrow-array/src/array/map_array.rs b/arrow-array/src/array/map_array.rs index 86608d586f34..02f9a35eb627 100644 --- a/arrow-array/src/array/map_array.rs +++ b/arrow-array/src/array/map_array.rs @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -use crate::array::{get_offsets, print_long_array}; +use crate::array::{get_offsets_from_buffer, print_long_array}; use crate::iterator::MapArrayIter; use crate::{Array, ArrayAccessor, ArrayRef, ListArray, StringArray, StructArray, make_array}; use arrow_buffer::{ArrowNativeType, Buffer, NullBuffer, OffsetBuffer, ToByteSlice}; @@ -272,28 +272,29 @@ impl From for ArrayData { impl MapArray { fn try_new_from_array_data(data: ArrayData) -> Result { - if !matches!(data.data_type(), DataType::Map(_, _)) { + let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts(); + + if !matches!(data_type, DataType::Map(_, _)) { return Err(ArrowError::InvalidArgumentError(format!( - "MapArray expected ArrayData with DataType::Map got {}", - data.data_type() + "MapArray expected ArrayData with DataType::Map got {data_type}", ))); } - if data.buffers().len() != 1 { + if buffers.len() != 1 { return Err(ArrowError::InvalidArgumentError(format!( "MapArray data should contain a single buffer only (value offsets), had {}", - data.len() + buffers.len(), ))); } + let buffer = buffers.pop().expect("checked above"); - if data.child_data().len() != 1 { + if child_data.len() != 1 { return Err(ArrowError::InvalidArgumentError(format!( "MapArray should contain a single child array (values array), had {}", - data.child_data().len() + child_data.len() ))); } - - let entries = data.child_data()[0].clone(); + let entries = child_data.pop().expect("checked above"); if let DataType::Struct(fields) = entries.data_type() { if fields.len() != 2 { @@ -312,11 +313,11 @@ impl MapArray { // SAFETY: // ArrayData is valid, and verified type above - let value_offsets = unsafe { get_offsets(&data) }; + let value_offsets = unsafe { get_offsets_from_buffer(buffer, offset, len) }; Ok(Self { - data_type: data.data_type().clone(), - nulls: data.nulls().cloned(), + data_type, + nulls, entries, value_offsets, })