From bbc8f04db2f1916de2385620c10c5293bacaf102 Mon Sep 17 00:00:00 2001 From: Sebastian Rabenhorst Date: Tue, 5 May 2026 10:12:18 -0400 Subject: [PATCH] Pre-size dedup HashTable in GenericByteDictionaryBuilder::with_capacity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `with_capacity` left the internal dedup `HashTable` at default capacity (0), forcing 0 → 4 → 8 → 16 → … resize+rehash cycles on the first inserts even when callers passed a non-zero `value_capacity`. `new()` already sizes the dedup table from the keys-builder capacity; `with_capacity` should do the same from `value_capacity`. Adds a regression test asserting `dedup.capacity() >= value_capacity` after construction. Closes #9907. Co-authored-by: AI --- .../generic_bytes_dictionary_builder.rs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) 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,