From d05733bce8b3f451ce7a9d7a83ba85aa57c58b77 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:26:38 +0200 Subject: [PATCH 01/23] remove spurious physical type checks --- parquet/src/encodings/encoding/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index eeabcf4ba5ce..88e5e2b00fd0 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -594,7 +594,7 @@ impl DeltaLengthByteArrayEncoder { impl Encoder for DeltaLengthByteArrayEncoder { fn put(&mut self, values: &[T::T]) -> Result<()> { ensure_phys_ty!( - Type::BYTE_ARRAY | Type::FIXED_LEN_BYTE_ARRAY, + Type::BYTE_ARRAY, "DeltaLengthByteArrayEncoder only supports ByteArrayType" ); @@ -628,7 +628,7 @@ impl Encoder for DeltaLengthByteArrayEncoder { fn flush_buffer(&mut self) -> Result { ensure_phys_ty!( - Type::BYTE_ARRAY | Type::FIXED_LEN_BYTE_ARRAY, + Type::BYTE_ARRAY, "DeltaLengthByteArrayEncoder only supports ByteArrayType" ); From c2f88d7d2e9de250152858678a3899d17efda33d Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:27:16 +0200 Subject: [PATCH 02/23] prealloc tmp buffers --- parquet/src/encodings/encoding/mod.rs | 39 +++++++++++++-------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 88e5e2b00fd0..6b09a13701c0 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -598,18 +598,18 @@ impl Encoder for DeltaLengthByteArrayEncoder { "DeltaLengthByteArrayEncoder only supports ByteArrayType" ); - let val_it = || { - values - .iter() - .map(|x| x.as_any().downcast_ref::().unwrap()) - }; + let values = values + .iter() + .map(|x| x.as_any().downcast_ref::().unwrap()); - let lengths: Vec = val_it().map(|byte_array| byte_array.len() as i32).collect(); - self.len_encoder.put(&lengths)?; - for byte_array in val_it() { - self.encoded_size += byte_array.len(); + let mut lengths: Vec = Vec::with_capacity(values.len()); + for byte_array in values { + let len = byte_array.len(); + lengths.push(len as i32); + self.encoded_size += len; self.data.push(byte_array.clone()); } + self.len_encoder.put(&lengths)?; Ok(()) } @@ -682,19 +682,16 @@ impl DeltaByteArrayEncoder { impl Encoder for DeltaByteArrayEncoder { fn put(&mut self, values: &[T::T]) -> Result<()> { - let mut prefix_lengths: Vec = vec![]; - let mut suffixes: Vec = vec![]; + let mut prefix_lengths: Vec = Vec::with_capacity(values.len()); + let mut suffixes: Vec = Vec::with_capacity(values.len()); - let values = values - .iter() - .map(|x| x.as_any()) - .map(|x| match T::get_physical_type() { - Type::BYTE_ARRAY => x.downcast_ref::().unwrap(), - Type::FIXED_LEN_BYTE_ARRAY => x.downcast_ref::().unwrap(), - _ => panic!( - "DeltaByteArrayEncoder only supports ByteArrayType and FixedLenByteArrayType" - ), - }); + let values = values.iter().map(|x| match T::get_physical_type() { + Type::BYTE_ARRAY => x.as_any().downcast_ref::().unwrap(), + Type::FIXED_LEN_BYTE_ARRAY => x.as_any().downcast_ref::().unwrap(), + _ => panic!( + "DeltaByteArrayEncoder only supports ByteArrayType and FixedLenByteArrayType" + ), + }); for byte_array in values { let current = byte_array.data(); From 6d97161955a1c7c05a0a38db9031e1ab2f44f6e4 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:05:20 +0200 Subject: [PATCH 03/23] add Encoder::flush_to --- .../encoding/byte_stream_split_encoder.rs | 40 ++++++------ .../src/encodings/encoding/dict_encoder.rs | 6 ++ parquet/src/encodings/encoding/mod.rs | 61 ++++++++++++------- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/parquet/src/encodings/encoding/byte_stream_split_encoder.rs b/parquet/src/encodings/encoding/byte_stream_split_encoder.rs index 0726c6b1c919..3fa0ddbb9a9c 100644 --- a/parquet/src/encodings/encoding/byte_stream_split_encoder.rs +++ b/parquet/src/encodings/encoding/byte_stream_split_encoder.rs @@ -22,7 +22,7 @@ use crate::errors::{ParquetError, Result}; use super::Encoder; -use bytes::{BufMut, Bytes}; +use bytes::BufMut; use std::cmp; use std::marker::PhantomData; @@ -88,12 +88,15 @@ impl Encoder for ByteStreamSplitEncoder { self.buffer.len() } - fn flush_buffer(&mut self) -> Result { - let mut encoded = vec![0; self.buffer.len()]; + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { + let start = out.len(); + out.resize(start + self.buffer.len(), 0); + let encoded = &mut out[start..]; + let type_size = T::get_type_size(); match type_size { - 4 => split_streams_const::<4>(&self.buffer, &mut encoded), - 8 => split_streams_const::<8>(&self.buffer, &mut encoded), + 4 => split_streams_const::<4>(&self.buffer, encoded), + 8 => split_streams_const::<8>(&self.buffer, encoded), _ => { return Err(general_err!( "byte stream split unsupported for data types of size {} bytes", @@ -103,7 +106,7 @@ impl Encoder for ByteStreamSplitEncoder { } self.buffer.clear(); - Ok(encoded.into()) + Ok(()) } /// return the estimated memory size of this encoder. @@ -202,26 +205,29 @@ impl Encoder for VariableWidthByteStreamSplitEncoder { self.buffer.len() } - fn flush_buffer(&mut self) -> Result { - let mut encoded = vec![0; self.buffer.len()]; + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { + let start = out.len(); + out.resize(start + self.buffer.len(), 0); + let encoded = &mut out[start..]; + let type_size = match T::get_physical_type() { Type::FIXED_LEN_BYTE_ARRAY => self.type_width, _ => T::get_type_size(), }; // split_streams_const() is faster up to type_width == 8 match type_size { - 2 => split_streams_const::<2>(&self.buffer, &mut encoded), - 3 => split_streams_const::<3>(&self.buffer, &mut encoded), - 4 => split_streams_const::<4>(&self.buffer, &mut encoded), - 5 => split_streams_const::<5>(&self.buffer, &mut encoded), - 6 => split_streams_const::<6>(&self.buffer, &mut encoded), - 7 => split_streams_const::<7>(&self.buffer, &mut encoded), - 8 => split_streams_const::<8>(&self.buffer, &mut encoded), - _ => split_streams_variable(&self.buffer, &mut encoded, type_size), + 2 => split_streams_const::<2>(&self.buffer, encoded), + 3 => split_streams_const::<3>(&self.buffer, encoded), + 4 => split_streams_const::<4>(&self.buffer, encoded), + 5 => split_streams_const::<5>(&self.buffer, encoded), + 6 => split_streams_const::<6>(&self.buffer, encoded), + 7 => split_streams_const::<7>(&self.buffer, encoded), + 8 => split_streams_const::<8>(&self.buffer, encoded), + _ => split_streams_variable(&self.buffer, out, type_size), } self.buffer.clear(); - Ok(encoded.into()) + Ok(()) } /// return the estimated memory size of this encoder. diff --git a/parquet/src/encodings/encoding/dict_encoder.rs b/parquet/src/encodings/encoding/dict_encoder.rs index 89666bbe7313..cd89a3c8db96 100644 --- a/parquet/src/encodings/encoding/dict_encoder.rs +++ b/parquet/src/encodings/encoding/dict_encoder.rs @@ -184,6 +184,12 @@ impl Encoder for DictEncoder { self.write_indices() } + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { + // TODO: RleEncoder could be reused instead of consumed + out.extend_from_slice(&self.flush_buffer()?); + Ok(()) + } + /// Returns the estimated total memory usage /// /// For this encoder, the indices are unencoded bytes (refer to [`Self::write_indices`]). diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 6b09a13701c0..37e68e5930bc 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -75,7 +75,15 @@ pub trait Encoder: Send { /// Flushes the underlying byte buffer that's being processed by this encoder, and /// return the immutable copy of it. This will also reset the internal state. - fn flush_buffer(&mut self) -> Result; + fn flush_buffer(&mut self) -> Result { + let mut buffer = Vec::new(); + self.flush_to(&mut buffer)?; + Ok(buffer.into()) + } + + /// Flushes the underlying byte buffer that's being processed by this encoder. + /// This will also reset the internal state. + fn flush_to(&mut self, out: &mut Vec) -> Result<()>; } /// Gets a encoder for the particular data type `T` and encoding `encoding`. Memory usage @@ -164,6 +172,15 @@ impl Encoder for PlainEncoder { Ok(std::mem::take(&mut self.buffer).into()) } + #[inline] + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { + out.extend_from_slice(&self.buffer); + out.extend_from_slice(self.bit_writer.flush_buffer()); + self.buffer.clear(); + self.bit_writer.clear(); + Ok(()) + } + #[inline] fn put(&mut self, values: &[T::T]) -> Result<()> { T::T::encode(values, &mut self.buffer, &mut self.bit_writer)?; @@ -260,6 +277,12 @@ impl Encoder for RleValueEncoder { Ok(buf.into()) } + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { + // TODO: RleEncoder could be reused instead of consumed + out.extend_from_slice(&self.flush_buffer()?); + Ok(()) + } + /// return the estimated memory size of this encoder. fn estimated_memory_size(&self) -> usize { self.encoder @@ -477,18 +500,17 @@ impl Encoder for DeltaBitPackEncoder { } fn estimated_data_encoded_size(&self) -> usize { - self.bit_writer.bytes_written() + self.page_header_writer.bytes_written() + self.bit_writer.bytes_written() } - fn flush_buffer(&mut self) -> Result { + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { // Write remaining values self.flush_block_values()?; // Write page header with total values self.write_page_header(); - let mut buffer = Vec::new(); - buffer.extend_from_slice(self.page_header_writer.flush_buffer()); - buffer.extend_from_slice(self.bit_writer.flush_buffer()); + out.extend_from_slice(self.page_header_writer.flush_buffer()); + out.extend_from_slice(self.bit_writer.flush_buffer()); // Reset state self.page_header_writer.clear(); @@ -498,7 +520,7 @@ impl Encoder for DeltaBitPackEncoder { self.current_value = 0; self.values_in_block = 0; - Ok(buffer.into()) + Ok(()) } /// return the estimated memory size of this encoder. @@ -626,22 +648,22 @@ impl Encoder for DeltaLengthByteArrayEncoder { self.len_encoder.estimated_data_encoded_size() + self.encoded_size } - fn flush_buffer(&mut self) -> Result { + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { ensure_phys_ty!( Type::BYTE_ARRAY, "DeltaLengthByteArrayEncoder only supports ByteArrayType" ); - let mut total_bytes = vec![]; - let lengths = self.len_encoder.flush_buffer()?; - total_bytes.extend_from_slice(&lengths); + out.reserve(self.estimated_data_encoded_size()); + self.len_encoder.flush_to(out)?; + self.data.iter().for_each(|byte_array| { - total_bytes.extend_from_slice(byte_array.data()); + out.extend_from_slice(byte_array.data()); }); self.data.clear(); self.encoded_size = 0; - Ok(total_bytes.into()) + Ok(()) } /// return the estimated memory size of this encoder. @@ -727,21 +749,16 @@ impl Encoder for DeltaByteArrayEncoder { + self.suffix_writer.estimated_data_encoded_size() } - fn flush_buffer(&mut self) -> Result { + fn flush_to(&mut self, out: &mut Vec) -> Result<()> { match T::get_physical_type() { Type::BYTE_ARRAY | Type::FIXED_LEN_BYTE_ARRAY => { - // TODO: investigate if we can merge lengths and suffixes - // without copying data into new vector. - let mut total_bytes = vec![]; // Insert lengths ... - let lengths = self.prefix_len_encoder.flush_buffer()?; - total_bytes.extend_from_slice(&lengths); + self.prefix_len_encoder.flush_to(out)?; // ... followed by suffixes - let suffixes = self.suffix_writer.flush_buffer()?; - total_bytes.extend_from_slice(&suffixes); + self.suffix_writer.flush_to(out)?; self.previous.clear(); - Ok(total_bytes.into()) + Ok(()) } _ => panic!( "DeltaByteArrayEncoder only supports ByteArrayType and FixedLenByteArrayType" From 2ffbf7723654ebf37b35001be9f56286cb2498a7 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:13:21 +0200 Subject: [PATCH 04/23] remove excessive [cold] attribs --- .../src/encodings/encoding/dict_encoder.rs | 3 --- parquet/src/encodings/encoding/mod.rs | 20 ------------------- 2 files changed, 23 deletions(-) diff --git a/parquet/src/encodings/encoding/dict_encoder.rs b/parquet/src/encodings/encoding/dict_encoder.rs index cd89a3c8db96..2feb77644101 100644 --- a/parquet/src/encodings/encoding/dict_encoder.rs +++ b/parquet/src/encodings/encoding/dict_encoder.rs @@ -164,9 +164,6 @@ impl Encoder for DictEncoder { Ok(()) } - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. fn encoding(&self) -> Encoding { Encoding::PLAIN_DICTIONARY } diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 37e68e5930bc..ef37c6b852af 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -152,10 +152,6 @@ impl PlainEncoder { } impl Encoder for PlainEncoder { - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. - #[cold] fn encoding(&self) -> Encoding { Encoding::PLAIN } @@ -242,10 +238,6 @@ impl Encoder for RleValueEncoder { Ok(()) } - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. - #[cold] fn encoding(&self) -> Encoding { Encoding::RLE } @@ -491,10 +483,6 @@ impl Encoder for DeltaBitPackEncoder { Ok(()) } - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. - #[cold] fn encoding(&self) -> Encoding { Encoding::DELTA_BINARY_PACKED } @@ -636,10 +624,6 @@ impl Encoder for DeltaLengthByteArrayEncoder { Ok(()) } - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. - #[cold] fn encoding(&self) -> Encoding { Encoding::DELTA_LENGTH_BYTE_ARRAY } @@ -736,10 +720,6 @@ impl Encoder for DeltaByteArrayEncoder { Ok(()) } - // Performance Note: - // As far as can be seen these functions are rarely called and as such we can hint to the - // compiler that they dont need to be folded into hot locations in the final output. - #[cold] fn encoding(&self) -> Encoding { Encoding::DELTA_BYTE_ARRAY } From 7236dd925e91bfa5eb149a5130c57881404a73f5 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:19:01 +0200 Subject: [PATCH 05/23] reuse length buffer on encoder --- parquet/src/encodings/encoding/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index ef37c6b852af..46719baded3f 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -576,6 +576,8 @@ impl DeltaBitPackEncoderConversion for DeltaBitPackEncoder { pub struct DeltaLengthByteArrayEncoder { // length encoder len_encoder: DeltaBitPackEncoder, + // length buffer + lengths: Vec, // byte array data data: Vec, // data size in bytes of encoded values @@ -594,6 +596,7 @@ impl DeltaLengthByteArrayEncoder { pub fn new() -> Self { Self { len_encoder: DeltaBitPackEncoder::new(), + lengths: vec![], data: vec![], encoded_size: 0, _phantom: PhantomData, @@ -612,14 +615,15 @@ impl Encoder for DeltaLengthByteArrayEncoder { .iter() .map(|x| x.as_any().downcast_ref::().unwrap()); - let mut lengths: Vec = Vec::with_capacity(values.len()); + self.lengths.reserve(values.len()); for byte_array in values { let len = byte_array.len(); - lengths.push(len as i32); + self.lengths.push(len as i32); self.encoded_size += len; self.data.push(byte_array.clone()); } - self.len_encoder.put(&lengths)?; + self.len_encoder.put(&self.lengths)?; + self.lengths.clear(); Ok(()) } From 1b891f86dcb6c6ab40d9cad7ce77737551673209 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:33:48 +0200 Subject: [PATCH 06/23] reuse+clone previous array instead of copying --- parquet/src/encodings/encoding/mod.rs | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 46719baded3f..aa7cdf6c3796 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -668,7 +668,7 @@ impl Encoder for DeltaLengthByteArrayEncoder { pub struct DeltaByteArrayEncoder { prefix_len_encoder: DeltaBitPackEncoder, suffix_writer: DeltaLengthByteArrayEncoder, - previous: Vec, + previous: ByteArray, _phantom: PhantomData, } @@ -684,7 +684,7 @@ impl DeltaByteArrayEncoder { Self { prefix_len_encoder: DeltaBitPackEncoder::new(), suffix_writer: DeltaLengthByteArrayEncoder::new(), - previous: vec![], + previous: ByteArray::new(), _phantom: PhantomData, } } @@ -703,21 +703,23 @@ impl Encoder for DeltaByteArrayEncoder { ), }); - for byte_array in values { - let current = byte_array.data(); - // Maximum prefix length that is shared between previous value and current - // value - let prefix_len = cmp::min(self.previous.len(), current.len()); + let mut previous_array = &self.previous; + for current_array in values { + let current = current_array.data(); + let previous = previous_array.data(); + // Maximum prefix length that is shared between previous value and current value + let prefix_len = cmp::min(previous.len(), current.len()); let mut match_len = 0; - while match_len < prefix_len && self.previous[match_len] == current[match_len] { + while match_len < prefix_len && previous[match_len] == current[match_len] { match_len += 1; } prefix_lengths.push(match_len as i32); - suffixes.push(byte_array.slice(match_len, byte_array.len() - match_len)); + suffixes.push(current_array.slice(match_len, current_array.len() - match_len)); // Update previous for the next prefix - self.previous.clear(); - self.previous.extend_from_slice(current); + previous_array = current_array; } + self.previous = previous_array.clone(); + self.prefix_len_encoder.put(&prefix_lengths)?; self.suffix_writer.put(&suffixes)?; @@ -741,7 +743,7 @@ impl Encoder for DeltaByteArrayEncoder { // ... followed by suffixes self.suffix_writer.flush_to(out)?; - self.previous.clear(); + self.previous = ByteArray::new(); Ok(()) } _ => panic!( @@ -754,7 +756,7 @@ impl Encoder for DeltaByteArrayEncoder { fn estimated_memory_size(&self) -> usize { self.prefix_len_encoder.estimated_memory_size() + self.suffix_writer.estimated_memory_size() - + (self.previous.capacity() * std::mem::size_of::()) + + (self.previous.len() * std::mem::size_of::()) } } From 34b573c4d73e7e522bdd7d603c9001852c725a7a Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:43:52 +0200 Subject: [PATCH 07/23] reuse buffers in DeltaByteArrayEncoder --- .../src/encodings/encoding/dict_encoder.rs | 2 ++ parquet/src/encodings/encoding/mod.rs | 24 ++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/parquet/src/encodings/encoding/dict_encoder.rs b/parquet/src/encodings/encoding/dict_encoder.rs index 2feb77644101..f99fbd9f4bb7 100644 --- a/parquet/src/encodings/encoding/dict_encoder.rs +++ b/parquet/src/encodings/encoding/dict_encoder.rs @@ -132,6 +132,8 @@ impl DictEncoder { /// Writes out the dictionary values with RLE encoding in a byte buffer, and return /// the result. pub fn write_indices(&mut self) -> Result { + // TODO: Move this into flush_buffer/flush_to? + // That could allow reusing buffer with flush_to. let buffer_len = self.estimated_data_encoded_size(); let mut buffer = Vec::with_capacity(buffer_len); buffer.push(self.bit_width()); diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index aa7cdf6c3796..8ab5fc7f3dad 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -81,7 +81,7 @@ pub trait Encoder: Send { Ok(buffer.into()) } - /// Flushes the underlying byte buffer that's being processed by this encoder. + /// Flushes the underlying byte buffer that's being processed by this encoder. /// This will also reset the internal state. fn flush_to(&mut self, out: &mut Vec) -> Result<()>; } @@ -668,6 +668,8 @@ impl Encoder for DeltaLengthByteArrayEncoder { pub struct DeltaByteArrayEncoder { prefix_len_encoder: DeltaBitPackEncoder, suffix_writer: DeltaLengthByteArrayEncoder, + prefix_lengths: Vec, + suffixes: Vec, previous: ByteArray, _phantom: PhantomData, } @@ -684,6 +686,8 @@ impl DeltaByteArrayEncoder { Self { prefix_len_encoder: DeltaBitPackEncoder::new(), suffix_writer: DeltaLengthByteArrayEncoder::new(), + prefix_lengths: Vec::new(), + suffixes: Vec::new(), previous: ByteArray::new(), _phantom: PhantomData, } @@ -692,8 +696,8 @@ impl DeltaByteArrayEncoder { impl Encoder for DeltaByteArrayEncoder { fn put(&mut self, values: &[T::T]) -> Result<()> { - let mut prefix_lengths: Vec = Vec::with_capacity(values.len()); - let mut suffixes: Vec = Vec::with_capacity(values.len()); + self.prefix_lengths.reserve(values.len()); + self.suffixes.reserve(values.len()); let values = values.iter().map(|x| match T::get_physical_type() { Type::BYTE_ARRAY => x.as_any().downcast_ref::().unwrap(), @@ -713,15 +717,19 @@ impl Encoder for DeltaByteArrayEncoder { while match_len < prefix_len && previous[match_len] == current[match_len] { match_len += 1; } - prefix_lengths.push(match_len as i32); - suffixes.push(current_array.slice(match_len, current_array.len() - match_len)); + self.prefix_lengths.push(match_len as i32); + self.suffixes + .push(current_array.slice(match_len, current.len() - match_len)); // Update previous for the next prefix previous_array = current_array; } self.previous = previous_array.clone(); - - self.prefix_len_encoder.put(&prefix_lengths)?; - self.suffix_writer.put(&suffixes)?; + + self.prefix_len_encoder.put(&self.prefix_lengths)?; + self.suffix_writer.put(&self.suffixes)?; + + self.prefix_lengths.clear(); + self.suffixes.clear(); Ok(()) } From fa68b834aca951f2a3084f1fb229b34fb06f3af7 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 22 Jul 2026 17:48:19 +0200 Subject: [PATCH 08/23] fix empty ByteArray panic --- parquet/src/encodings/encoding/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 8ab5fc7f3dad..a696cb27f047 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -688,7 +688,7 @@ impl DeltaByteArrayEncoder { suffix_writer: DeltaLengthByteArrayEncoder::new(), prefix_lengths: Vec::new(), suffixes: Vec::new(), - previous: ByteArray::new(), + previous: Bytes::new().into(), _phantom: PhantomData, } } @@ -751,7 +751,7 @@ impl Encoder for DeltaByteArrayEncoder { // ... followed by suffixes self.suffix_writer.flush_to(out)?; - self.previous = ByteArray::new(); + self.previous = Bytes::new().into(); Ok(()) } _ => panic!( From 893196aae23465269bd3e9dfe109671811b1afd1 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Thu, 23 Jul 2026 14:12:13 +0200 Subject: [PATCH 09/23] avoid keeping ByteArray alive in DeltaByteArrayEncoder --- parquet/src/encodings/encoding/mod.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index a696cb27f047..00939349a95f 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -670,7 +670,7 @@ pub struct DeltaByteArrayEncoder { suffix_writer: DeltaLengthByteArrayEncoder, prefix_lengths: Vec, suffixes: Vec, - previous: ByteArray, + previous: Vec, _phantom: PhantomData, } @@ -688,7 +688,7 @@ impl DeltaByteArrayEncoder { suffix_writer: DeltaLengthByteArrayEncoder::new(), prefix_lengths: Vec::new(), suffixes: Vec::new(), - previous: Bytes::new().into(), + previous: Vec::new(), _phantom: PhantomData, } } @@ -707,10 +707,10 @@ impl Encoder for DeltaByteArrayEncoder { ), }); - let mut previous_array = &self.previous; + let mut previous = self.previous.as_slice(); + let mut previous_array = &ByteArray::from(Bytes::new()); for current_array in values { let current = current_array.data(); - let previous = previous_array.data(); // Maximum prefix length that is shared between previous value and current value let prefix_len = cmp::min(previous.len(), current.len()); let mut match_len = 0; @@ -721,9 +721,11 @@ impl Encoder for DeltaByteArrayEncoder { self.suffixes .push(current_array.slice(match_len, current.len() - match_len)); // Update previous for the next prefix + previous = current; previous_array = current_array; } - self.previous = previous_array.clone(); + self.previous.clear(); + self.previous.extend_from_slice(previous_array.data()); self.prefix_len_encoder.put(&self.prefix_lengths)?; self.suffix_writer.put(&self.suffixes)?; @@ -751,7 +753,7 @@ impl Encoder for DeltaByteArrayEncoder { // ... followed by suffixes self.suffix_writer.flush_to(out)?; - self.previous = Bytes::new().into(); + self.previous.clear(); Ok(()) } _ => panic!( From 47af80db1977ee0d82fd7444a3b503f60e1df0a0 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Thu, 23 Jul 2026 14:17:27 +0200 Subject: [PATCH 10/23] use capacity over len again --- parquet/src/encodings/encoding/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parquet/src/encodings/encoding/mod.rs b/parquet/src/encodings/encoding/mod.rs index 00939349a95f..867a348f6be3 100644 --- a/parquet/src/encodings/encoding/mod.rs +++ b/parquet/src/encodings/encoding/mod.rs @@ -766,7 +766,7 @@ impl Encoder for DeltaByteArrayEncoder { fn estimated_memory_size(&self) -> usize { self.prefix_len_encoder.estimated_memory_size() + self.suffix_writer.estimated_memory_size() - + (self.previous.len() * std::mem::size_of::()) + + (self.previous.capacity() * std::mem::size_of::()) } } From 92c6230297423ce6fe3b13fb5e792e608d388fd0 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 15 Jul 2026 11:48:15 +0200 Subject: [PATCH 11/23] perf: use Cursor in ZSTDCodec to avoid Vec alloc and copy --- Cargo.lock | 4599 ++++++++++++++++++++++++++++++++++++ parquet/Cargo.toml | 3 +- parquet/src/compression.rs | 28 +- 3 files changed, 4620 insertions(+), 10 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000000..9edbc167677c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4599 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" + +[[package]] +name = "apache-avro" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36fa98bc79671c7981272d91a8753a928ff6a1cd8e4f20a44c45bd5d313840bf" +dependencies = [ + "bigdecimal", + "bon", + "digest 0.10.7", + "log", + "miniz_oxide", + "num-bigint", + "quad-rand", + "rand 0.9.4", + "regex-lite", + "serde", + "serde_bytes", + "serde_json", + "strum", + "strum_macros 0.27.2", + "thiserror 2.0.18", + "uuid", +] + +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arrow" +version = "58.3.0" +dependencies = [ + "arrow-arith", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-csv", + "arrow-data", + "arrow-ipc", + "arrow-json", + "arrow-ord", + "arrow-pyarrow", + "arrow-row", + "arrow-schema", + "arrow-select", + "arrow-string", + "bytes", + "chrono", + "criterion", + "half", + "memmap2", + "rand 0.9.4", + "serde", +] + +[[package]] +name = "arrow-arith" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "num-traits", +] + +[[package]] +name = "arrow-array" +version = "58.3.0" +dependencies = [ + "ahash", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "chrono-tz", + "criterion", + "futures", + "half", + "hashbrown 0.17.1", + "num-complex", + "num-integer", + "num-traits", + "rand 0.9.4", +] + +[[package]] +name = "arrow-avro" +version = "58.3.0" +dependencies = [ + "apache-avro", + "arrow", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "async-stream", + "bytes", + "bzip2", + "crc", + "criterion", + "flate2", + "futures", + "half", + "indexmap", + "liblzma", + "md5", + "num-bigint", + "object_store", + "once_cell", + "rand 0.9.4", + "serde", + "serde_json", + "sha2", + "snap", + "strum_macros 0.28.0", + "tempfile", + "tokio", + "uuid", + "zstd", +] + +[[package]] +name = "arrow-buffer" +version = "58.3.0" +dependencies = [ + "bytes", + "criterion", + "half", + "num-bigint", + "num-traits", + "rand 0.9.4", +] + +[[package]] +name = "arrow-cast" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-ord", + "arrow-schema", + "arrow-select", + "atoi", + "base64", + "chrono", + "comfy-table", + "criterion", + "half", + "insta", + "lexical-core", + "num-traits", + "rand 0.9.4", + "ryu", +] + +[[package]] +name = "arrow-csv" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-schema", + "bytes", + "chrono", + "csv", + "csv-core", + "futures", + "regex", + "tempfile", + "tokio", +] + +[[package]] +name = "arrow-data" +version = "58.3.0" +dependencies = [ + "arrow-buffer", + "arrow-schema", + "half", + "num-integer", + "num-traits", +] + +[[package]] +name = "arrow-flight" +version = "58.3.0" +dependencies = [ + "anyhow", + "arrow-arith", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-ipc", + "arrow-ord", + "arrow-row", + "arrow-schema", + "arrow-select", + "arrow-string", + "assert_cmd", + "base64", + "bytes", + "clap", + "futures", + "http", + "http-body", + "hyper-util", + "once_cell", + "paste", + "pin-project-lite", + "prost", + "prost-types", + "tempfile", + "tokio", + "tokio-stream", + "tonic", + "tonic-prost", + "tower", + "tracing-log", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "arrow-integration-test" +version = "58.3.0" +dependencies = [ + "arrow", + "arrow-buffer", + "hex", + "num-bigint", + "num-traits", + "serde", + "serde_json", +] + +[[package]] +name = "arrow-integration-testing" +version = "58.3.0" +dependencies = [ + "arrow", + "arrow-buffer", + "arrow-flight", + "arrow-integration-test", + "clap", + "flate2", + "futures", + "prost", + "serde_json", + "tempfile", + "tokio", + "tonic", + "tracing-subscriber", +] + +[[package]] +name = "arrow-ipc" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "bytes", + "criterion", + "flatbuffers", + "lz4_flex", + "memmap2", + "tempfile", + "tokio", + "zstd", +] + +[[package]] +name = "arrow-json" +version = "58.3.0" +dependencies = [ + "arbitrary", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-ord", + "arrow-schema", + "arrow-select", + "bytes", + "chrono", + "criterion", + "flate2", + "futures", + "half", + "indexmap", + "itoa", + "lexical-core", + "memchr", + "num-traits", + "rand 0.9.4", + "ryu", + "serde", + "serde_core", + "serde_json", + "simdutf8", + "tokio", +] + +[[package]] +name = "arrow-ord" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "half", + "rand 0.9.4", +] + +[[package]] +name = "arrow-pyarrow" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-data", + "arrow-schema", + "pyo3", +] + +[[package]] +name = "arrow-row" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-ord", + "arrow-schema", + "arrow-select", + "half", + "rand 0.9.4", +] + +[[package]] +name = "arrow-schema" +version = "58.3.0" +dependencies = [ + "bitflags", + "criterion", + "insta", + "postcard", + "serde", + "serde_core", + "serde_json", +] + +[[package]] +name = "arrow-select" +version = "58.3.0" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num-traits", + "rand 0.9.4", +] + +[[package]] +name = "arrow-string" +version = "58.3.0" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "memchr", + "num-traits", + "regex", + "regex-syntax", +] + +[[package]] +name = "assert_cmd" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aa3a22042e45de04255c7bf3626e239f450200fd0493c1e382263544b20aea6" +dependencies = [ + "anstyle", + "bstr", + "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-lc-rs" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bigdecimal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" +dependencies = [ + "autocfg", + "libm", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "bon" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f47dbe92550676ee653353c310dfb9cf6ba17ee70396e1f7cf0a2020ad49b2fe" +dependencies = [ + "bon-macros", + "rustversion", +] + +[[package]] +name = "bon-macros" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c" +dependencies = [ + "darling", + "ident_case", + "prettyplease", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "brotli" +version = "8.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "bzip2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" +dependencies = [ + "libbz2-rs-sys", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.2.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core 0.10.1", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", + "terminal_size", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.18", +] + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "comfy-table" +version = "7.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958c5d6ecf1f214b4c2bbbbf6ab9523a864bd136dcf71a7e8904799acfe1ad47" +dependencies = [ + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "futures", + "itertools 0.13.0", + "num-traits", + "oorandom", + "page_size", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools 0.13.0", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "const-oid", + "crypto-common 0.2.1", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flatbuffers" +version = "25.12.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" +dependencies = [ + "bitflags", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", + "zlib-rs", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gen" +version = "0.1.0" +dependencies = [ + "prost-build", + "tonic-prost-build", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "geo-traits" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7c353d12a704ccfab1ba8bfb1a7fe6cb18b665bf89d37f4f7890edcd260206" +dependencies = [ + "geo-types", +] + +[[package]] +name = "geo-types" +version = "0.7.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94776032c45f950d30a13af6113c2ad5625316c9abfbccee4dd5a6695f8fe0f5" +dependencies = [ + "approx", + "num-traits", + "serde", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasip2", + "wasip3", +] + +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", + "rand 0.9.4", + "rand_distr", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + +[[package]] +name = "hybrid-array" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" + +[[package]] +name = "icu_provider" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "insta" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "lexical-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d8d125a277f807e55a77304455eb7b1cb52f2b18c143b60e766c120bd64a594" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a9f232fbd6f550bc0137dcb5f99ab674071ac2d690ac69704593cb4abbea56" +dependencies = [ + "lexical-parse-integer", + "lexical-util", +] + +[[package]] +name = "lexical-parse-integer" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a7a039f8fb9c19c996cd7b2fcce303c1b2874fe1aca544edc85c4a5f8489b34" +dependencies = [ + "lexical-util", +] + +[[package]] +name = "lexical-util" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" + +[[package]] +name = "lexical-write-float" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c438c87c013188d415fbabbb1dceb44249ab81664efbd31b14ae55dabb6361" +dependencies = [ + "lexical-util", + "lexical-write-integer", +] + +[[package]] +name = "lexical-write-integer" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "409851a618475d2d5796377cad353802345cba92c867d9fbcde9cf4eac4e14df" +dependencies = [ + "lexical-util", +] + +[[package]] +name = "libbz2-rs-sys" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "liblzma" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6033b77c21d1f56deeae8014eb9fbe7bdf1765185a6c508b5ca82eeaed7f899" +dependencies = [ + "liblzma-sys", +] + +[[package]] +name = "liblzma-sys" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a60851d15cd8c5346eca4ab8babff585be2ae4bc8097c067291d3ffe2add3b6" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lz4_flex" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "md5" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebb8d8732c6a6df3d8f032a82911cfc747e00efb95cc46e8d0acd5b5b88570c" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memmap2" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" +dependencies = [ + "libc", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c863e9ab5e7bf9c99ba75e1050f1e4d624ae87ed3532d6238ffbdc7b585dbbe6" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "object_store" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622acbc9100d3c10e2ee15804b0caa40e55c933d5aa53814cd520805b7958a49" +dependencies = [ + "async-trait", + "base64", + "bytes", + "chrono", + "form_urlencoded", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body-util", + "httparse", + "humantime", + "hyper", + "itertools 0.14.0", + "parking_lot", + "percent-encoding", + "quick-xml", + "rand 0.10.1", + "reqwest", + "ring", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror 2.0.18", + "tokio", + "tracing", + "url", + "walkdir", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "parquet" +version = "58.3.0" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-csv", + "arrow-data", + "arrow-ipc", + "arrow-schema", + "arrow-select", + "base64", + "brotli", + "bytes", + "chrono", + "clap", + "crc32fast", + "criterion", + "flate2", + "futures", + "half", + "hashbrown 0.17.1", + "insta", + "lz4_flex", + "num-bigint", + "num-integer", + "num-traits", + "object_store", + "parquet-geospatial", + "parquet-variant", + "parquet-variant-compute", + "parquet-variant-json", + "paste", + "rand 0.9.4", + "ring", + "seq-macro", + "serde", + "serde_json", + "simdutf8", + "snap", + "sysinfo", + "tempfile", + "thrift", + "tokio", + "twox-hash", + "zstd", + "zstd-safe", +] + +[[package]] +name = "parquet-geospatial" +version = "58.3.0" +dependencies = [ + "arrow-schema", + "geo-traits", + "serde", + "serde_json", + "wkb", + "wkt", +] + +[[package]] +name = "parquet-variant" +version = "58.3.0" +dependencies = [ + "arrow", + "arrow-schema", + "chrono", + "criterion", + "half", + "indexmap", + "num-traits", + "paste", + "rand 0.9.4", + "simdutf8", + "uuid", +] + +[[package]] +name = "parquet-variant-compute" +version = "58.3.0" +dependencies = [ + "arrow", + "arrow-schema", + "chrono", + "criterion", + "half", + "indexmap", + "parquet-variant", + "parquet-variant-json", + "rand 0.9.4", + "serde_json", + "uuid", +] + +[[package]] +name = "parquet-variant-json" +version = "58.3.0" +dependencies = [ + "arrow-schema", + "base64", + "chrono", + "parquet-variant", + "serde_json", + "uuid", +] + +[[package]] +name = "parquet_derive" +version = "58.3.0" +dependencies = [ + "parquet", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parquet_derive_test" +version = "58.3.0" +dependencies = [ + "chrono", + "parquet", + "parquet_derive", + "uuid", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", +] + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "predicates" +version = "3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" + +[[package]] +name = "predicates-tree" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +dependencies = [ + "heck", + "itertools 0.14.0", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + +[[package]] +name = "pyo3" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12" +dependencies = [ + "libc", + "once_cell", + "portable-atomic", + "pyo3-build-config", + "pyo3-ffi", +] + +[[package]] +name = "pyo3-build-config" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e" +dependencies = [ + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "quad-rand" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a651516ddc9168ebd67b24afd085a718be02f8858fe406591b013d101ce2f40" + +[[package]] +name = "quick-xml" +version = "0.39.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.4", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_distr" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" +dependencies = [ + "num-traits", + "rand 0.9.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "seq-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.3", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sysinfo" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows", +] + +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "terminal_size" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" +dependencies = [ + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "thrift" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e54bc85fc7faa8bc175c4bab5b92ba8d9a3ce893d0e9f42cc455c8ab16a9e09" +dependencies = [ + "byteorder", + "integer-encoding", + "ordered-float", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "tonic" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +dependencies = [ + "async-trait", + "axum", + "base64", + "bytes", + "flate2", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "rustls-native-certs", + "socket2", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", + "webpki-roots", + "zstd", +] + +[[package]] +name = "tonic-build" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tonic-prost" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn", + "tempfile", + "tonic-build", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "thread_local", + "tracing", + "tracing-core", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a" +dependencies = [ + "getrandom 0.4.2", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "web-sys" +version = "0.3.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "wkb" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a120b336c7ad17749026d50427c23d838ecb50cd64aaea6254b5030152f890a9" +dependencies = [ + "byteorder", + "geo-traits", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "wkt" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb2b923ccc882312e559ffaa832a055ba9d1ac0cc8e86b3e25453247e4b81d7" +dependencies = [ + "geo-traits", + "geo-types", + "log", + "num-traits", + "thiserror 1.0.69", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zlib-rs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/parquet/Cargo.toml b/parquet/Cargo.toml index 9f4d2a33df0c..9f16ae313719 100644 --- a/parquet/Cargo.toml +++ b/parquet/Cargo.toml @@ -59,6 +59,7 @@ brotli = { version = "8.0", default-features = false, features = ["std"], option flate2 = { version = "1.1", default-features = false, optional = true } lz4_flex = { version = "0.13", default-features = false, features = ["std", "frame"], optional = true } zstd = { version = "0.13", optional = true, default-features = false } +zstd-safe = { version = "7.2", optional = true, default-features = false } chrono = { workspace = true } num-bigint = { version = "0.4", default-features = false } num-integer = { version = "0.1.46", default-features = false, features = ["std"] } @@ -120,7 +121,7 @@ async = ["futures", "tokio"] # Enable object_store integration object_store = ["dep:object_store", "async"] # Group Zstd dependencies -zstd = ["dep:zstd"] +zstd = ["dep:zstd", "dep:zstd-safe"] # Verify 32-bit CRC checksum when decoding parquet pages crc = ["dep:crc32fast"] # Enable SIMD UTF-8 validation diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index fe2fb59c5b8c..51d0e9668da0 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -505,6 +505,7 @@ pub use lz4_codec::*; mod zstd_codec { use crate::compression::{Codec, ZstdLevel}; use crate::errors::Result; + use std::io::Cursor; /// Codec for Zstandard compression algorithm. /// @@ -534,22 +535,31 @@ mod zstd_codec { output_buf: &mut Vec, uncompress_size: Option, ) -> Result { + let offset = output_buf.len(); let capacity = uncompress_size.unwrap_or_else(|| { // Get the decompressed size from the zstd frame header - zstd::zstd_safe::get_frame_content_size(input_buf) - .ok() - .flatten() - .unwrap_or(input_buf.len() as u64 * 4) as usize + // See doc of upper_bound about "experimental" feature. + zstd::bulk::Decompressor::upper_bound(input_buf) + .unwrap_or(input_buf.len().saturating_mul(4)) }); - let decompressed = self.decompressor.decompress(input_buf, capacity)?; - let len = decompressed.len(); - output_buf.extend_from_slice(&decompressed); + output_buf.reserve(capacity); + + let mut cursor = Cursor::new(output_buf); + cursor.set_position(offset as u64); + let len = self + .decompressor + .decompress_to_buffer(input_buf, &mut cursor)?; Ok(len) } fn compress(&mut self, input_buf: &[u8], output_buf: &mut Vec) -> Result<()> { - let compressed = self.compressor.compress(input_buf)?; - output_buf.extend_from_slice(&compressed); + let offset = output_buf.len(); + let buffer_len = zstd_safe::compress_bound(input_buf.len()); + output_buf.reserve(buffer_len); + + let mut cursor = Cursor::new(output_buf); + cursor.set_position(offset as u64); + let _written = self.compressor.compress_to_buffer(input_buf, &mut cursor)?; Ok(()) } } From bee621537dd29fece84fc0f93e8af2a5e1f719ba Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:11:12 +0200 Subject: [PATCH 12/23] nit: rename vars --- parquet/src/compression.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 51d0e9668da0..2ab9e9249c8e 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -536,13 +536,13 @@ mod zstd_codec { uncompress_size: Option, ) -> Result { let offset = output_buf.len(); - let capacity = uncompress_size.unwrap_or_else(|| { - // Get the decompressed size from the zstd frame header + let len = uncompress_size.unwrap_or_else(|| { + // Get the decompressed size from the zstd frame header. // See doc of upper_bound about "experimental" feature. zstd::bulk::Decompressor::upper_bound(input_buf) .unwrap_or(input_buf.len().saturating_mul(4)) }); - output_buf.reserve(capacity); + output_buf.reserve(len); let mut cursor = Cursor::new(output_buf); cursor.set_position(offset as u64); @@ -554,8 +554,8 @@ mod zstd_codec { fn compress(&mut self, input_buf: &[u8], output_buf: &mut Vec) -> Result<()> { let offset = output_buf.len(); - let buffer_len = zstd_safe::compress_bound(input_buf.len()); - output_buf.reserve(buffer_len); + let len = zstd_safe::compress_bound(input_buf.len()); + output_buf.reserve(len); let mut cursor = Cursor::new(output_buf); cursor.set_position(offset as u64); From 1e5b390f48d5a9b20d5bf7c24f1ec658778ed161 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:41:26 +0200 Subject: [PATCH 13/23] use zstd::zstd_safe re-export --- Cargo.lock | 1 - parquet/Cargo.toml | 3 +-- parquet/src/compression.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9edbc167677c..8a3a1296a2a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2374,7 +2374,6 @@ dependencies = [ "tokio", "twox-hash", "zstd", - "zstd-safe", ] [[package]] diff --git a/parquet/Cargo.toml b/parquet/Cargo.toml index 9f16ae313719..9f4d2a33df0c 100644 --- a/parquet/Cargo.toml +++ b/parquet/Cargo.toml @@ -59,7 +59,6 @@ brotli = { version = "8.0", default-features = false, features = ["std"], option flate2 = { version = "1.1", default-features = false, optional = true } lz4_flex = { version = "0.13", default-features = false, features = ["std", "frame"], optional = true } zstd = { version = "0.13", optional = true, default-features = false } -zstd-safe = { version = "7.2", optional = true, default-features = false } chrono = { workspace = true } num-bigint = { version = "0.4", default-features = false } num-integer = { version = "0.1.46", default-features = false, features = ["std"] } @@ -121,7 +120,7 @@ async = ["futures", "tokio"] # Enable object_store integration object_store = ["dep:object_store", "async"] # Group Zstd dependencies -zstd = ["dep:zstd", "dep:zstd-safe"] +zstd = ["dep:zstd"] # Verify 32-bit CRC checksum when decoding parquet pages crc = ["dep:crc32fast"] # Enable SIMD UTF-8 validation diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 2ab9e9249c8e..2170e6db15c8 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -554,7 +554,7 @@ mod zstd_codec { fn compress(&mut self, input_buf: &[u8], output_buf: &mut Vec) -> Result<()> { let offset = output_buf.len(); - let len = zstd_safe::compress_bound(input_buf.len()); + let len = zstd::zstd_safe::compress_bound(input_buf.len()); output_buf.reserve(len); let mut cursor = Cursor::new(output_buf); From d95272e8b0ab943a61f74fc1918111fd81ff245a Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:52:18 +0200 Subject: [PATCH 14/23] clarify upper_bound comment --- parquet/src/compression.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 2170e6db15c8..6c4ca79c4d22 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -537,7 +537,7 @@ mod zstd_codec { ) -> Result { let offset = output_buf.len(); let len = uncompress_size.unwrap_or_else(|| { - // Get the decompressed size from the zstd frame header. + // Get the decompressed size of all zstd frames in the input. // See doc of upper_bound about "experimental" feature. zstd::bulk::Decompressor::upper_bound(input_buf) .unwrap_or(input_buf.len().saturating_mul(4)) From 999bfeb98e919dbbdb70509726ef53dd4db5d5c9 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:35:35 +0200 Subject: [PATCH 15/23] restore get_frame_content_size and remove upper_bound --- parquet/src/compression.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/parquet/src/compression.rs b/parquet/src/compression.rs index 6c4ca79c4d22..6f3a18fe60b0 100644 --- a/parquet/src/compression.rs +++ b/parquet/src/compression.rs @@ -536,12 +536,15 @@ mod zstd_codec { uncompress_size: Option, ) -> Result { let offset = output_buf.len(); - let len = uncompress_size.unwrap_or_else(|| { - // Get the decompressed size of all zstd frames in the input. - // See doc of upper_bound about "experimental" feature. - zstd::bulk::Decompressor::upper_bound(input_buf) - .unwrap_or(input_buf.len().saturating_mul(4)) - }); + let len = uncompress_size + .or_else(|| { + // Get the decompressed size from the zstd frame header + zstd::zstd_safe::get_frame_content_size(input_buf) + .ok() + .flatten() + .map(|size| size as usize) + }) + .unwrap_or(input_buf.len().saturating_mul(4)); output_buf.reserve(len); let mut cursor = Cursor::new(output_buf); From 1dfbcdee964a4172493aa32a75c9ff219c66fac0 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:30:47 +0200 Subject: [PATCH 16/23] split one contiguous Bytes instead of allocating ByteArray per element --- parquet/src/arrow/arrow_writer/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 641b81257a91..7ed19327c3be 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1632,12 +1632,20 @@ fn get_decimal_128_array_slice( array: &arrow_array::Decimal128Array, indices: &[usize], ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); let size = decimal_length_from_precision(array.precision()); + let mut arena = Vec::with_capacity(indices.len() * size); + let mut values = Vec::with_capacity(indices.len()); + for i in indices { let as_be_bytes = array.value(*i).to_be_bytes(); - let resized_value = as_be_bytes[(16 - size)..].to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(resized_value))); + let resized_value = &as_be_bytes[(16 - size)..]; + arena.extend_from_slice(resized_value); + } + + let mut arena = Bytes::from(arena); + while arena.len() >= size { + let slice = arena.split_to(size); + values.push(FixedLenByteArray::from(ByteArray::from(slice))); } values } From b44f7882ea7b2553f9aad2f0a0979b636f05d273 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:51:42 +0200 Subject: [PATCH 17/23] chunk_contiguous_vec for all decimal types, f16, and fsb --- parquet/src/arrow/arrow_writer/mod.rs | 148 ++++++++++++++------------ 1 file changed, 77 insertions(+), 71 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 7ed19327c3be..7b48365f7ef0 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -27,8 +27,8 @@ use std::sync::{Arc, Mutex}; use std::vec::IntoIter; use arrow_array::cast::AsArray; -use arrow_array::types::*; use arrow_array::{ArrayRef, Int32Array, RecordBatch, RecordBatchWriter}; +use arrow_array::{PrimitiveArray, types::*}; use arrow_schema::{ ArrowError, DataType as ArrowDataType, Field, IntervalUnit, SchemaRef, TimeUnit, }; @@ -1514,19 +1514,19 @@ fn write_leaf( } ArrowDataType::Decimal32(_, _) => { let array = column.as_primitive::(); - get_decimal_32_array_slice(array, indices) + get_decimal_array_slice(array, indices.iter().copied()) } ArrowDataType::Decimal64(_, _) => { let array = column.as_primitive::(); - get_decimal_64_array_slice(array, indices) + get_decimal_array_slice(array, indices.iter().copied()) } ArrowDataType::Decimal128(_, _) => { let array = column.as_primitive::(); - get_decimal_128_array_slice(array, indices) + get_decimal_array_slice(array, indices.iter().copied()) } ArrowDataType::Decimal256(_, _) => { let array = column.as_primitive::(); - get_decimal_256_array_slice(array, indices) + get_decimal_array_slice(array, indices.iter().copied()) } ArrowDataType::Float16 => { let array = column.as_primitive::(); @@ -1573,14 +1573,15 @@ fn get_interval_ym_array_slice( array: &arrow_array::IntervalYearMonthArray, indices: &[usize], ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); + const VALUE_SIZE: usize = 12; + let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); for i in indices { - let mut value = array.value(*i).to_le_bytes().to_vec(); - let mut suffix = vec![0; 8]; - value.append(&mut suffix); - values.push(FixedLenByteArray::from(ByteArray::from(value))) + let mut out = [0; 12]; + let value = array.value(i); + out[0..4].copy_from_slice(&value.to_le_bytes()); + arena.extend_from_slice(&out); } - values + chunk_contiguous_vec(arena, VALUE_SIZE) } /// Returns 12-byte values representing 3 values of months, days and milliseconds (4-bytes each). @@ -1589,101 +1590,106 @@ fn get_interval_dt_array_slice( array: &arrow_array::IntervalDayTimeArray, indices: &[usize], ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); + const VALUE_SIZE: usize = 12; + let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); for i in indices { - let mut out = [0; 12]; + let mut out = [0; VALUE_SIZE]; let value = array.value(*i); out[4..8].copy_from_slice(&value.days.to_le_bytes()); out[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); - values.push(FixedLenByteArray::from(ByteArray::from(out.to_vec()))); + arena.extend_from_slice(&out); } - values + chunk_contiguous_vec(arena, VALUE_SIZE) } -fn get_decimal_32_array_slice( - array: &arrow_array::Decimal32Array, - indices: &[usize], -) -> Vec { - let mut values = Vec::with_capacity(indices.len()); - let size = decimal_length_from_precision(array.precision()); - for i in indices { - let as_be_bytes = array.value(*i).to_be_bytes(); - let resized_value = as_be_bytes[(4 - size)..].to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(resized_value))); - } - values +trait NativeDecimalType: DecimalType { + type NativeBytes: AsRef<[u8]>; + + fn to_be_bytes(value: Self::Native) -> Self::NativeBytes; } +impl NativeDecimalType for Decimal32Type { + type NativeBytes = [u8; Self::BYTE_LENGTH]; -fn get_decimal_64_array_slice( - array: &arrow_array::Decimal64Array, - indices: &[usize], -) -> Vec { - let mut values = Vec::with_capacity(indices.len()); - let size = decimal_length_from_precision(array.precision()); - for i in indices { - let as_be_bytes = array.value(*i).to_be_bytes(); - let resized_value = as_be_bytes[(8 - size)..].to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(resized_value))); + fn to_be_bytes(value: Self::Native) -> Self::NativeBytes { + value.to_be_bytes() } - values } +impl NativeDecimalType for Decimal64Type { + type NativeBytes = [u8; Self::BYTE_LENGTH]; -fn get_decimal_128_array_slice( - array: &arrow_array::Decimal128Array, - indices: &[usize], -) -> Vec { - let size = decimal_length_from_precision(array.precision()); - let mut arena = Vec::with_capacity(indices.len() * size); - let mut values = Vec::with_capacity(indices.len()); + fn to_be_bytes(value: Self::Native) -> Self::NativeBytes { + value.to_be_bytes() + } +} +impl NativeDecimalType for Decimal128Type { + type NativeBytes = [u8; Self::BYTE_LENGTH]; - for i in indices { - let as_be_bytes = array.value(*i).to_be_bytes(); - let resized_value = &as_be_bytes[(16 - size)..]; - arena.extend_from_slice(resized_value); + fn to_be_bytes(value: Self::Native) -> Self::NativeBytes { + value.to_be_bytes() } +} +impl NativeDecimalType for Decimal256Type { + type NativeBytes = [u8; Self::BYTE_LENGTH]; - let mut arena = Bytes::from(arena); - while arena.len() >= size { - let slice = arena.split_to(size); - values.push(FixedLenByteArray::from(ByteArray::from(slice))); + fn to_be_bytes(value: Self::Native) -> Self::NativeBytes { + value.to_be_bytes() } - values } -fn get_decimal_256_array_slice( - array: &arrow_array::Decimal256Array, - indices: &[usize], +fn get_decimal_array_slice( + array: &PrimitiveArray, + indices: impl ExactSizeIterator, ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); - let size = decimal_length_from_precision(array.precision()); - for i in indices { - let as_be_bytes = array.value(*i).to_be_bytes(); - let resized_value = as_be_bytes[(32 - size)..].to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(resized_value))); + let value_size = decimal_length_from_precision(array.precision()); + let mut arena = Vec::with_capacity(indices.len() * value_size); + + if value_size == T::BYTE_LENGTH { + for i in indices { + let as_be_bytes = T::to_be_bytes(array.value(*i)); + arena.extend_from_slice(as_be_bytes.as_ref()); + } + } else { + for i in indices { + let as_be_bytes = T::to_be_bytes(array.value(*i)); + let resized_value = &as_be_bytes.as_ref()[(T::BYTE_LENGTH - value_size)..]; + arena.extend_from_slice(resized_value); + } } - values + chunk_contiguous_vec(arena, value_size) } fn get_float_16_array_slice( array: &arrow_array::Float16Array, indices: &[usize], ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); + const VALUE_SIZE: usize = size_of::<::Native>(); + let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); for i in indices { - let value = array.value(*i).to_le_bytes().to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(value))); + let value = array.value(i).to_le_bytes(); + arena.extend_from_slice(&value); } - values + chunk_contiguous_vec(arena, VALUE_SIZE) } fn get_fsb_array_slice( array: &arrow_array::FixedSizeBinaryArray, indices: &[usize], ) -> Vec { - let mut values = Vec::with_capacity(indices.len()); + let value_size = array.value_length() as usize; + let mut arena = Vec::with_capacity(indices.len() * value_size); for i in indices { - let value = array.value(*i).to_vec(); - values.push(FixedLenByteArray::from(ByteArray::from(value))) + let value = array.value(*i); + arena.extend_from_slice(value); + } + chunk_contiguous_vec(arena, value_size) +} + +fn chunk_contiguous_vec(arena: Vec, value_size: usize) -> Vec { + let mut values = Vec::with_capacity(arena.len() / value_size); + let mut arena = Bytes::from(arena); + while arena.len() >= value_size { + let slice = arena.split_to(value_size); + values.push(FixedLenByteArray::from(ByteArray::from(slice))); } values } From 23721715b7733c0d0ed4d098970445ad648fde1d Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:53:50 +0200 Subject: [PATCH 18/23] fix rebase errors --- parquet/src/arrow/arrow_writer/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 7b48365f7ef0..f1a7da26e688 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1594,7 +1594,7 @@ fn get_interval_dt_array_slice( let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); for i in indices { let mut out = [0; VALUE_SIZE]; - let value = array.value(*i); + let value = array.value(i); out[4..8].copy_from_slice(&value.days.to_le_bytes()); out[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); arena.extend_from_slice(&out); @@ -1645,12 +1645,12 @@ fn get_decimal_array_slice( if value_size == T::BYTE_LENGTH { for i in indices { - let as_be_bytes = T::to_be_bytes(array.value(*i)); + let as_be_bytes = T::to_be_bytes(array.value(i)); arena.extend_from_slice(as_be_bytes.as_ref()); } } else { for i in indices { - let as_be_bytes = T::to_be_bytes(array.value(*i)); + let as_be_bytes = T::to_be_bytes(array.value(i)); let resized_value = &as_be_bytes.as_ref()[(T::BYTE_LENGTH - value_size)..]; arena.extend_from_slice(resized_value); } @@ -1678,7 +1678,7 @@ fn get_fsb_array_slice( let value_size = array.value_length() as usize; let mut arena = Vec::with_capacity(indices.len() * value_size); for i in indices { - let value = array.value(*i); + let value = array.value(i); arena.extend_from_slice(value); } chunk_contiguous_vec(arena, value_size) From cc95eaeffd1c712772d228764afa8678194d10e2 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 18:26:26 +0200 Subject: [PATCH 19/23] Rewrite to use chunks_exact_mut. This allows optimizations since iterators uphold invariants. --- parquet/src/arrow/arrow_writer/mod.rs | 90 ++++++++++++++------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index f1a7da26e688..4b8ade7eb97d 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -21,7 +21,7 @@ use crate::column::chunker::ContentDefinedChunker; use bytes::Bytes; use std::io::{Read, Write}; -use std::iter::Peekable; +use std::mem::MaybeUninit; use std::slice::Iter; use std::sync::{Arc, Mutex}; use std::vec::IntoIter; @@ -1573,15 +1573,12 @@ fn get_interval_ym_array_slice( array: &arrow_array::IntervalYearMonthArray, indices: &[usize], ) -> Vec { - const VALUE_SIZE: usize = 12; - let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); - for i in indices { - let mut out = [0; 12]; + chunk_array_slice(12, indices, move |i, chunk| { let value = array.value(i); - out[0..4].copy_from_slice(&value.to_le_bytes()); - arena.extend_from_slice(&out); - } - chunk_contiguous_vec(arena, VALUE_SIZE) + chunk[0..4].write_copy_of_slice(&value.to_le_bytes()); + chunk[4..12].fill(MaybeUninit::new(0)); + unsafe { chunk.assume_init_mut() } + }) } /// Returns 12-byte values representing 3 values of months, days and milliseconds (4-bytes each). @@ -1590,16 +1587,13 @@ fn get_interval_dt_array_slice( array: &arrow_array::IntervalDayTimeArray, indices: &[usize], ) -> Vec { - const VALUE_SIZE: usize = 12; - let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); - for i in indices { - let mut out = [0; VALUE_SIZE]; + chunk_array_slice(12, indices, move |i, chunk| { let value = array.value(i); - out[4..8].copy_from_slice(&value.days.to_le_bytes()); - out[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); - arena.extend_from_slice(&out); - } - chunk_contiguous_vec(arena, VALUE_SIZE) + chunk[0..4].fill(MaybeUninit::new(0)); + chunk[4..8].write_copy_of_slice(&value.days.to_le_bytes()); + chunk[8..12].write_copy_of_slice(&value.milliseconds.to_le_bytes()); + unsafe { chunk.assume_init_mut() } + }) } trait NativeDecimalType: DecimalType { @@ -1640,55 +1634,63 @@ fn get_decimal_array_slice( array: &PrimitiveArray, indices: impl ExactSizeIterator, ) -> Vec { - let value_size = decimal_length_from_precision(array.precision()); - let mut arena = Vec::with_capacity(indices.len() * value_size); + let chunk_size = decimal_length_from_precision(array.precision()); + assert!(chunk_size <= T::BYTE_LENGTH); - if value_size == T::BYTE_LENGTH { - for i in indices { + if chunk_size == T::BYTE_LENGTH { + // Special-case that allows inlining memcpy. + chunk_array_slice(chunk_size, indices, move |i, chunk| { let as_be_bytes = T::to_be_bytes(array.value(i)); - arena.extend_from_slice(as_be_bytes.as_ref()); - } + chunk.write_copy_of_slice(as_be_bytes.as_ref()) + }) } else { - for i in indices { + chunk_array_slice(chunk_size, indices, move |i, chunk| { let as_be_bytes = T::to_be_bytes(array.value(i)); - let resized_value = &as_be_bytes.as_ref()[(T::BYTE_LENGTH - value_size)..]; - arena.extend_from_slice(resized_value); - } + let resized_value = &as_be_bytes.as_ref()[(T::BYTE_LENGTH - chunk.len())..]; + chunk.write_copy_of_slice(resized_value) + }) } - chunk_contiguous_vec(arena, value_size) } fn get_float_16_array_slice( array: &arrow_array::Float16Array, indices: &[usize], ) -> Vec { - const VALUE_SIZE: usize = size_of::<::Native>(); - let mut arena = Vec::with_capacity(indices.len() * VALUE_SIZE); - for i in indices { + chunk_array_slice(2, indices, move |i, chunk| { let value = array.value(i).to_le_bytes(); - arena.extend_from_slice(&value); - } - chunk_contiguous_vec(arena, VALUE_SIZE) + chunk.write_copy_of_slice(&value) + }) } fn get_fsb_array_slice( array: &arrow_array::FixedSizeBinaryArray, indices: &[usize], ) -> Vec { - let value_size = array.value_length() as usize; - let mut arena = Vec::with_capacity(indices.len() * value_size); - for i in indices { + chunk_array_slice(array.value_size(), indices, move |i, chunk| { let value = array.value(i); - arena.extend_from_slice(value); + chunk.write_copy_of_slice(value) + }) +} + +#[inline] +fn chunk_array_slice( + chunk_size: usize, + indices: impl ExactSizeIterator, + writer: impl Fn(usize, &mut [MaybeUninit]) -> &mut [u8], +) -> Vec { + let mut arena = Vec::with_capacity(indices.len() * chunk_size); + for (i, chunk) in indices.zip(arena.spare_capacity_mut().chunks_exact_mut(chunk_size)) { + let filled_chunk = writer(i, chunk); + debug_assert_eq!(filled_chunk.len(), chunk_size); } - chunk_contiguous_vec(arena, value_size) + chunk_contiguous_vec(arena, chunk_size) } -fn chunk_contiguous_vec(arena: Vec, value_size: usize) -> Vec { - let mut values = Vec::with_capacity(arena.len() / value_size); +fn chunk_contiguous_vec(arena: Vec, chunk_size: usize) -> Vec { + let mut values = Vec::with_capacity(arena.len() / chunk_size); let mut arena = Bytes::from(arena); - while arena.len() >= value_size { - let slice = arena.split_to(value_size); + while arena.len() >= chunk_size { + let slice = arena.split_to(chunk_size); values.push(FixedLenByteArray::from(ByteArray::from(slice))); } values From 833d939bf5569f95c094fae2a5157c1acefb741b Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 18:57:20 +0200 Subject: [PATCH 20/23] set_len on Vec --- parquet/src/arrow/arrow_writer/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 4b8ade7eb97d..7b9493a9a870 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1678,10 +1678,15 @@ fn chunk_array_slice( indices: impl ExactSizeIterator, writer: impl Fn(usize, &mut [MaybeUninit]) -> &mut [u8], ) -> Vec { - let mut arena = Vec::with_capacity(indices.len() * chunk_size); + let capacity = indices.len() * chunk_size; + let mut arena = Vec::with_capacity(capacity); for (i, chunk) in indices.zip(arena.spare_capacity_mut().chunks_exact_mut(chunk_size)) { let filled_chunk = writer(i, chunk); - debug_assert_eq!(filled_chunk.len(), chunk_size); + assert_eq!(filled_chunk.len(), chunk_size); + } + // SAFETY: all chunks were initialized with writer closure + unsafe { + arena.set_len(capacity); } chunk_contiguous_vec(arena, chunk_size) } From 28d50e6e355f928300d9d4296c7ffaf051b36a32 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 19:50:51 +0200 Subject: [PATCH 21/23] go back to tmp bufs --- parquet/src/arrow/arrow_writer/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 7b9493a9a870..58504cbbdfd9 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -1574,10 +1574,10 @@ fn get_interval_ym_array_slice( indices: &[usize], ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { + let mut out = [0; 12]; let value = array.value(i); - chunk[0..4].write_copy_of_slice(&value.to_le_bytes()); - chunk[4..12].fill(MaybeUninit::new(0)); - unsafe { chunk.assume_init_mut() } + out[0..4].copy_from_slice(&value.to_le_bytes()); + chunk.write_copy_of_slice(&out) }) } @@ -1588,11 +1588,11 @@ fn get_interval_dt_array_slice( indices: &[usize], ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { + let mut out = [0; 12]; let value = array.value(i); - chunk[0..4].fill(MaybeUninit::new(0)); - chunk[4..8].write_copy_of_slice(&value.days.to_le_bytes()); - chunk[8..12].write_copy_of_slice(&value.milliseconds.to_le_bytes()); - unsafe { chunk.assume_init_mut() } + out[4..8].copy_from_slice(&value.days.to_le_bytes()); + out[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); + chunk.write_copy_of_slice(&out) }) } @@ -1684,7 +1684,7 @@ fn chunk_array_slice( let filled_chunk = writer(i, chunk); assert_eq!(filled_chunk.len(), chunk_size); } - // SAFETY: all chunks were initialized with writer closure + // SAFETY: all chunks were initialized with writer closure unsafe { arena.set_len(capacity); } From 032f2b65f89f6edc8951b58b0c66ca657e09d85d Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 20 Jul 2026 21:32:34 +0200 Subject: [PATCH 22/23] Make changes compatible with MSRV 1.85. Revert this when MSRV is bumped to at least 1.93. --- parquet/src/arrow/arrow_writer/mod.rs | 34 ++++++++++----------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index 58504cbbdfd9..a4be52a02a44 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -21,7 +21,6 @@ use crate::column::chunker::ContentDefinedChunker; use bytes::Bytes; use std::io::{Read, Write}; -use std::mem::MaybeUninit; use std::slice::Iter; use std::sync::{Arc, Mutex}; use std::vec::IntoIter; @@ -1574,10 +1573,8 @@ fn get_interval_ym_array_slice( indices: &[usize], ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { - let mut out = [0; 12]; let value = array.value(i); - out[0..4].copy_from_slice(&value.to_le_bytes()); - chunk.write_copy_of_slice(&out) + chunk[0..4].copy_from_slice(&value.to_le_bytes()); }) } @@ -1588,11 +1585,9 @@ fn get_interval_dt_array_slice( indices: &[usize], ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { - let mut out = [0; 12]; let value = array.value(i); - out[4..8].copy_from_slice(&value.days.to_le_bytes()); - out[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); - chunk.write_copy_of_slice(&out) + chunk[4..8].copy_from_slice(&value.days.to_le_bytes()); + chunk[8..12].copy_from_slice(&value.milliseconds.to_le_bytes()); }) } @@ -1641,13 +1636,13 @@ fn get_decimal_array_slice( // Special-case that allows inlining memcpy. chunk_array_slice(chunk_size, indices, move |i, chunk| { let as_be_bytes = T::to_be_bytes(array.value(i)); - chunk.write_copy_of_slice(as_be_bytes.as_ref()) + chunk.copy_from_slice(as_be_bytes.as_ref()); }) } else { chunk_array_slice(chunk_size, indices, move |i, chunk| { let as_be_bytes = T::to_be_bytes(array.value(i)); let resized_value = &as_be_bytes.as_ref()[(T::BYTE_LENGTH - chunk.len())..]; - chunk.write_copy_of_slice(resized_value) + chunk.copy_from_slice(resized_value); }) } } @@ -1658,7 +1653,7 @@ fn get_float_16_array_slice( ) -> Vec { chunk_array_slice(2, indices, move |i, chunk| { let value = array.value(i).to_le_bytes(); - chunk.write_copy_of_slice(&value) + chunk.copy_from_slice(&value); }) } @@ -1668,7 +1663,7 @@ fn get_fsb_array_slice( ) -> Vec { chunk_array_slice(array.value_size(), indices, move |i, chunk| { let value = array.value(i); - chunk.write_copy_of_slice(value) + chunk.copy_from_slice(value); }) } @@ -1676,17 +1671,14 @@ fn get_fsb_array_slice( fn chunk_array_slice( chunk_size: usize, indices: impl ExactSizeIterator, - writer: impl Fn(usize, &mut [MaybeUninit]) -> &mut [u8], + writer: impl Fn(usize, &mut [u8]), ) -> Vec { let capacity = indices.len() * chunk_size; - let mut arena = Vec::with_capacity(capacity); - for (i, chunk) in indices.zip(arena.spare_capacity_mut().chunks_exact_mut(chunk_size)) { - let filled_chunk = writer(i, chunk); - assert_eq!(filled_chunk.len(), chunk_size); - } - // SAFETY: all chunks were initialized with writer closure - unsafe { - arena.set_len(capacity); + // TODO: This could be done with Vec::spare_capacity_mut, + // but [MaybeUninit]::write_copy_of_slice is gated behind MSRV 1.93 + let mut arena = vec![0; capacity]; + for (i, chunk) in indices.zip(arena.chunks_exact_mut(chunk_size)) { + writer(i, chunk); } chunk_contiguous_vec(arena, chunk_size) } From 965f97e4a0b4b5ddd01ec2ef182c07a195f6e435 Mon Sep 17 00:00:00 2001 From: Michal Piatkowski <291740709+MassivePizza@users.noreply.github.com> Date: Mon, 27 Jul 2026 14:37:52 +0200 Subject: [PATCH 23/23] fix cherry-picks --- parquet/src/arrow/arrow_writer/mod.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/parquet/src/arrow/arrow_writer/mod.rs b/parquet/src/arrow/arrow_writer/mod.rs index a4be52a02a44..3f62a06f6b04 100644 --- a/parquet/src/arrow/arrow_writer/mod.rs +++ b/parquet/src/arrow/arrow_writer/mod.rs @@ -21,9 +21,11 @@ use crate::column::chunker::ContentDefinedChunker; use bytes::Bytes; use std::io::{Read, Write}; +use std::iter::Peekable; use std::slice::Iter; use std::sync::{Arc, Mutex}; use std::vec::IntoIter; +use std::{unimplemented, unreachable}; use arrow_array::cast::AsArray; use arrow_array::{ArrayRef, Int32Array, RecordBatch, RecordBatchWriter}; @@ -1495,11 +1497,11 @@ fn write_leaf( ArrowDataType::Interval(interval_unit) => match interval_unit { IntervalUnit::YearMonth => { let array = column.as_primitive::(); - get_interval_ym_array_slice(array, indices) + get_interval_ym_array_slice(array, indices.iter().copied()) } IntervalUnit::DayTime => { let array = column.as_primitive::(); - get_interval_dt_array_slice(array, indices) + get_interval_dt_array_slice(array, indices.iter().copied()) } _ => { return Err(ParquetError::NYI(format!( @@ -1509,7 +1511,7 @@ fn write_leaf( }, ArrowDataType::FixedSizeBinary(_) => { let array = column.as_fixed_size_binary(); - get_fsb_array_slice(array, indices) + get_fsb_array_slice(array, indices.iter().copied()) } ArrowDataType::Decimal32(_, _) => { let array = column.as_primitive::(); @@ -1529,7 +1531,7 @@ fn write_leaf( } ArrowDataType::Float16 => { let array = column.as_primitive::(); - get_float_16_array_slice(array, indices) + get_float_16_array_slice(array, indices.iter().copied()) } _ => { return Err(ParquetError::NYI( @@ -1570,7 +1572,7 @@ fn get_bool_array_slice(array: &arrow_array::BooleanArray, indices: &[usize]) -> /// An Arrow YearMonth interval only stores months, thus only the first 4 bytes are populated. fn get_interval_ym_array_slice( array: &arrow_array::IntervalYearMonthArray, - indices: &[usize], + indices: impl ExactSizeIterator, ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { let value = array.value(i); @@ -1582,7 +1584,7 @@ fn get_interval_ym_array_slice( /// An Arrow DayTime interval only stores days and millis, thus the first 4 bytes are not populated. fn get_interval_dt_array_slice( array: &arrow_array::IntervalDayTimeArray, - indices: &[usize], + indices: impl ExactSizeIterator, ) -> Vec { chunk_array_slice(12, indices, move |i, chunk| { let value = array.value(i); @@ -1649,7 +1651,7 @@ fn get_decimal_array_slice( fn get_float_16_array_slice( array: &arrow_array::Float16Array, - indices: &[usize], + indices: impl ExactSizeIterator, ) -> Vec { chunk_array_slice(2, indices, move |i, chunk| { let value = array.value(i).to_le_bytes(); @@ -1659,9 +1661,9 @@ fn get_float_16_array_slice( fn get_fsb_array_slice( array: &arrow_array::FixedSizeBinaryArray, - indices: &[usize], + indices: impl ExactSizeIterator, ) -> Vec { - chunk_array_slice(array.value_size(), indices, move |i, chunk| { + chunk_array_slice(array.value_length() as usize, indices, move |i, chunk| { let value = array.value(i); chunk.copy_from_slice(value); })