[Parquet] ALP encoder/decoder support - #9372
Conversation
|
amaaazing |
|
@alamb I worked with codex on replicating the c++ implementation reviewing commit by commit. I'll do one final read myself, but this should be ready for initial review. |
|
Thank you -- I will put this on my short list to reivew I was out last week |
|
@devanbenz Sorry for taking so long to address your comments. I'll make sure to work on it this week! |
devanbenz
left a comment
There was a problem hiding this comment.
Comment about header regarding publication of spec.
|
Thanks @devanbenz, I've finally addressed your reviews! |
Please cargo fmt the code 🫡 |
|
|
The results would be dataset dependent. Not sure we can get a reliable benchmark using random generated ones. |
Yes for sure -- I think we can start with using data from the paper as a starting point (they list several datasets) |
Some of them are here - https://github.com/cwida/ALP/tree/main/benchmarks I'll work on the benchmarks PR |
I think there is two usecases:
|
devanbenz
left a comment
There was a problem hiding this comment.
Just the one comment, spent the morning looking over this PR and playing around with it locally. It is a very large body of work, looks good to me. My comment is non-blocking but maybe something to look in to.
| + self.streaming.estimated_memory_size() | ||
| } | ||
|
|
||
| fn flush_buffer(&mut self) -> Result<Bytes> { |
There was a problem hiding this comment.
Can this ever be called when an encoder has no values set or null value? For example, if you create a new encoder with AlpEncoder::<DoubleType>::new() and call flush_buffer all while later pages have well behaved data. Will it cause issues? Could you add a test for this if it's possible?
There was a problem hiding this comment.
Maybe something like:
#[test]
fn test_empty_first_page() {
let mut encoder = AlpEncoder::<DoubleType>::new();
// First page flushed with no values
let empty = encoder.flush_buffer().unwrap();
assert_eq!(empty.len(), ALP_HEADER_SIZE);
// Later pages carry well-behaved decimal data.
let values: Vec<f64> = (0..1500).map(|i| (i as f64) * 0.01).collect();
encoder.put(&values).unwrap();
let page = encoder.flush_buffer().unwrap();
assert!(page.len() < values.len() * 8);
}There was a problem hiding this comment.
I think it's the same issue @alamb mentioned above -
If the first data page of a column chunk has zero non-null values, build_preset(&[]) fixes the scale at 10^0, so every non-integer value in all later pages of that chunk becomes an exception
Since an all-null leading page is a realistic input, this is probably something we should fix (as a follow on PR)
We'll add this as a follow up
|
Added the parquet-rewrite wiring here - 5e9ad1c |
|
FWIW I plan to merge this once the upstream parquet-testing PR is merged. I will prod the upstream PR tomorrow at the parquet sync |
|
added #10785 to update the parquet-testing dep |
|
Added another one with just the pinned rev change - #10786 |
# Conflicts: # parquet-testing # parquet/src/encodings/encoding/mod.rs
|
BTW if you want to see a sneak preview of a blog post about what ALP is |
|
@alamb @devanbenz thanks for your help 🙏 |
Yes, I don't see a problem with that. It's in "preview" in the spec, and it requires opt-in from users.
Yes thanks to all for getting this done so soon! |
|
sounds good; i was hoping to take a proper look at this since ive just skimmed it, but kept getting sidetracked by other PRs 😅 |
I think we still have some more time until the 60 release -- so we can wait a while to merge it in |
Which issue does this PR close?
Rationale for this change
check issue
What changes are included in this PR?
Are these changes tested?
Are there any user-facing changes?