Skip to content

Commit 5b4a6e8

Browse files
committed
Merge remote-tracking branch 'origin/main' into parquet-reader-bench-baseline
2 parents a5c636b + be66461 commit 5b4a6e8

10 files changed

Lines changed: 346 additions & 32 deletions

File tree

.github/workflows/rust.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ jobs:
118118
uses: ./.github/actions/setup-builder
119119
- name: Install cargo-msrv (if needed)
120120
# cargo-msrv binary may be cached by the cargo cache step in setup-builder, and cargo install will error if it is already installed
121-
run: if which cargo-msrv ; then echo "using existing cargo-msrv binary" ; else cargo install cargo-msrv ; fi
121+
# --locked uses cargo-msrv's pinned Cargo.lock; without it an unpinned transitive
122+
# dep (aws-runtime) resolves to a version that fails to compile (E0282)
123+
run: if which cargo-msrv ; then echo "using existing cargo-msrv binary" ; else cargo install cargo-msrv --locked ; fi
122124
- name: Check all packages
123125
run: |
124126
# run `cargo msrv verify --manifest-path "path/to/Cargo.toml"` to see problematic dependencies

Cargo.lock

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

arrow-pyarrow-integration-testing/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ crate-type = ["cdylib"]
3434

3535
[dependencies]
3636
arrow = { path = "../arrow", features = ["pyarrow"] }
37-
pyo3 = { version = "0.28.0", features = ["extension-module"] }
37+
pyo3 = { version = "0.29.0", features = ["extension-module"] }

arrow-pyarrow-testing/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ publish = false
4848
# Note no dependency on arrow, to ensure arrow-pyarrow can be used by itself
4949
arrow-array = { path = "../arrow-array" }
5050
arrow-pyarrow = { path = "../arrow-pyarrow" }
51-
pyo3 = { version = "0.28.0", default-features = false }
51+
pyo3 = { version = "0.29.0", default-features = false }

arrow-pyarrow/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ all-features = true
3939
arrow-array = { workspace = true, features = ["ffi"] }
4040
arrow-data = { workspace = true }
4141
arrow-schema = { workspace = true }
42-
pyo3 = { version = "0.28.0", default-features = false }
42+
pyo3 = { version = "0.29.0", default-features = false }

arrow-pyarrow/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ fn validate_pycapsule(capsule: &Bound<PyCapsule>, name: &str) -> PyResult<()> {
139139
));
140140
}
141141

142-
let capsule_name = unsafe { capsule_name.unwrap().as_cstr().to_str()? };
142+
let capsule_name = unsafe { capsule_name.unwrap().as_cstr() }
143+
.to_str()
144+
.map_err(|e| PyValueError::new_err(e.to_string()))?;
143145
if capsule_name != name {
144146
return Err(PyValueError::new_err(format!(
145147
"Expected name '{name}' in PyCapsule, instead got '{capsule_name}'",

parquet/benches/arrow_writer.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ fn create_string_dictionary_bench_batch(
159159
true_density,
160160
)?)
161161
}
162-
// commenting out until implementation of RunEndEncoded is complete. See https://github.com/apache/arrow-rs/pull/9936#discussion_r3242936421
163-
#[allow(dead_code)]
164162
fn create_ree_bench_batch(
165163
value_dt: DataType,
166164
size: usize,
167-
null_density: f32,
165+
null_pct: Option<u8>,
168166
true_density: f32,
169167
) -> Result<RecordBatch> {
168+
const DEFAULT_NULL_PCT: u8 = 10;
169+
let null_density = null_pct.unwrap_or(DEFAULT_NULL_PCT) as f32 / 100.0;
170170
let fields = vec![Field::new(
171171
"_1",
172172
DataType::RunEndEncoded(
@@ -506,11 +506,24 @@ fn create_batches() -> Vec<(&'static str, RecordBatch)> {
506506
let batch = create_string_bench_batch_non_null(BATCH_SIZE, 0.25, 0.75).unwrap();
507507
batches.push(("string_non_null", batch));
508508

509-
//let batch = create_ree_bench_batch(DataType::Utf8, BATCH_SIZE, 0.25, 0.75).unwrap();
510-
//batches.push(("string_ree", batch));
509+
let batch = create_ree_bench_batch(DataType::Utf8, BATCH_SIZE, None, 0.75).unwrap();
510+
batches.push(("string_ree", batch));
511+
512+
let batch = create_ree_bench_batch(DataType::Int32, BATCH_SIZE, None, 0.75).unwrap();
513+
batches.push(("int32_ree", batch));
514+
515+
let batch = create_ree_bench_batch(DataType::Boolean, BATCH_SIZE, None, 0.75).unwrap();
516+
batches.push(("bool_ree", batch));
517+
518+
let batch =
519+
create_ree_bench_batch(DataType::FixedSizeBinary(16), BATCH_SIZE, None, 0.75).unwrap();
520+
batches.push(("fixed_size_binary_ree", batch));
521+
522+
let batch = create_ree_bench_batch(DataType::Utf8, BATCH_SIZE, Some(95), 0.75).unwrap();
523+
batches.push(("string_ree_95pct_null", batch));
511524

512-
//let batch = create_ree_bench_batch(DataType::Int32, BATCH_SIZE, 0.25, 0.75).unwrap();
513-
//batches.push(("int32_ree", batch));
525+
let batch = create_ree_bench_batch(DataType::Int32, BATCH_SIZE, Some(95), 0.75).unwrap();
526+
batches.push(("int32_ree_95pct_null", batch));
514527

515528
let batch = create_float_bench_batch_with_nans(BATCH_SIZE, 0.5).unwrap();
516529
batches.push(("float_with_nans", batch));

parquet/src/arrow/arrow_writer/levels.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,36 @@ use crate::column::chunker::CdcChunk;
4444
use crate::column::writer::LevelDataRef;
4545
use crate::errors::{ParquetError, Result};
4646
use arrow_array::cast::AsArray;
47-
use arrow_array::{Array, ArrayRef, OffsetSizeTrait};
47+
use arrow_array::types::RunEndIndexType;
48+
use arrow_array::{Array, ArrayRef, Int32Array, OffsetSizeTrait, RunArray, downcast_run_array};
4849
use arrow_buffer::bit_iterator::BitIndexIterator;
4950
use arrow_buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
5051
use arrow_schema::{DataType, Field};
5152
use std::ops::Range;
5253
use std::sync::Arc;
5354

55+
/// Expands a [`DataType::RunEndEncoded`] array into a flat (logical) array of its values type.
56+
///
57+
/// use `arrow_select::take` to materialize the full-length flat array.
58+
/// This is intentionally simple (O(n)); efficiency can/should be improved
59+
fn expand_ree_array(array: &ArrayRef) -> Result<ArrayRef> {
60+
downcast_run_array!(
61+
array => expand_typed_ree(array),
62+
_ => unreachable!("expand_ree_array called on non-REE array"),
63+
)
64+
}
65+
66+
fn expand_typed_ree<R: RunEndIndexType>(run_array: &RunArray<R>) -> Result<ArrayRef> {
67+
let run_ends = run_array.run_ends();
68+
let values = run_array.values();
69+
let len = run_array.len();
70+
let indices: Int32Array = (0..len)
71+
.map(|i| run_ends.get_physical_index(i) as i32)
72+
.collect();
73+
arrow_select::take::take(values.as_ref(), &indices, None)
74+
.map_err(|e| arrow_err!("Failed to expand REE array: {}", e))
75+
}
76+
5477
/// Performs a depth-first scan of the children of `array`, constructing [`ArrayLevels`]
5578
/// for each leaf column encountered
5679
pub(crate) fn calculate_array_levels(array: &ArrayRef, field: &Field) -> Result<Vec<ArrayLevels>> {
@@ -185,6 +208,15 @@ impl LevelInfoBuilder {
185208
let levels = ArrayLevels::new(parent_ctx, is_nullable, array.clone());
186209
Ok(Self::Primitive(levels))
187210
}
211+
DataType::RunEndEncoded(_, value_field) => {
212+
let flat = expand_ree_array(array)?;
213+
let flat_field = Field::new(
214+
field.name(),
215+
value_field.data_type().clone(),
216+
field.is_nullable(),
217+
);
218+
Self::try_new(&flat_field, parent_ctx, &flat)
219+
}
188220
DataType::Struct(children) => {
189221
let array = array.as_struct();
190222
let def_level = match is_nullable {

0 commit comments

Comments
 (0)