diff --git a/arrow-array/src/builder/generic_bytes_dictionary_builder.rs b/arrow-array/src/builder/generic_bytes_dictionary_builder.rs index 956014a72b7d..4ce451aec81e 100644 --- a/arrow-array/src/builder/generic_bytes_dictionary_builder.rs +++ b/arrow-array/src/builder/generic_bytes_dictionary_builder.rs @@ -84,7 +84,7 @@ where ) -> Self { Self { state: Default::default(), - dedup: Default::default(), + dedup: HashTable::with_capacity(value_capacity), keys_builder: PrimitiveBuilder::with_capacity(keys_capacity), values_builder: GenericByteBuilder::::with_capacity(value_capacity, data_capacity), } @@ -647,6 +647,25 @@ mod tests { test_bytes_dictionary_builder::>(vec![b"abc", b"def"]); } + #[test] + fn test_with_capacity_presizes_dedup() { + // `with_capacity` must size the dedup `HashTable` from `value_capacity`, + // otherwise the first inserts force a chain of resize+rehash cycles. + let value_capacity = 128; + let builder = + GenericByteDictionaryBuilder::>::with_capacity( + 256, + value_capacity, + value_capacity * 32, + ); + assert!( + builder.dedup.capacity() >= value_capacity, + "dedup HashTable not pre-sized: got capacity {}, expected >= {}", + builder.dedup.capacity(), + value_capacity, + ); + } + fn test_bytes_dictionary_builder_finish_cloned(values: Vec<&T::Native>) where T: ByteArrayType,