Skip to content

feat: add custom Avro OCF reader for manifest parsing with filtered decoding#281

Merged
JingsongLi merged 1 commit intoapache:mainfrom
JingsongLi:avro_super_fast
Apr 25, 2026
Merged

feat: add custom Avro OCF reader for manifest parsing with filtered decoding#281
JingsongLi merged 1 commit intoapache:mainfrom
JingsongLi:avro_super_fast

Conversation

@JingsongLi
Copy link
Copy Markdown
Contributor

@JingsongLi JingsongLi commented Apr 23, 2026

Purpose

Replace apache-avro's read path (Value intermediate representation) with a zero-copy custom decoder that reads Avro binary directly into target structs. Key optimizations:

  • Custom AvroCursor for zero-copy Avro binary primitive decoding
  • OCF parser with snappy/deflate/zstd decompression support
  • Writer schema parsing with field index mapping for compatibility
  • Two-pass filtered ManifestEntry decoding: lightweight fields first, skip expensive DataFileMeta for filtered-out entries
  • SharedSchemaCache for cross-task schema reuse
  • Zero-copy entry consumption (into_identifier, into_parts)
  • Parallel base+delta manifest list reads via futures::try_join!
  • Remove redundant exists() checks before file reads

Benchmark for TableScan:

  1. Full Scan: consistent ~4x speedup across all sizes. Each manifest has ~22,369 entries at ~7.66 MB. The custom Avro OCF decoder with zero-copy cursor and two-pass filtered decoding is paying off nicely.
  2. Partial Scan: partition filtering scenarios is highly significant — 14.2x.

Brief change log

Tests

API and Format

Documentation

@JingsongLi JingsongLi closed this Apr 23, 2026
@JingsongLi JingsongLi reopened this Apr 23, 2026
…ecoding

Replace apache-avro's read path (Value intermediate representation) with
a zero-copy custom decoder that reads Avro binary directly into target
structs. Key optimizations:

- Custom AvroCursor for zero-copy Avro binary primitive decoding
- OCF parser with snappy/deflate/zstd decompression support
- Writer schema parsing with field index mapping for compatibility
- Two-pass filtered ManifestEntry decoding: lightweight fields first,
  skip expensive DataFileMeta for filtered-out entries
- SharedSchemaCache for cross-task schema reuse
- Zero-copy entry consumption (into_identifier, into_parts)
- Parallel base+delta manifest list reads via futures::try_join!
- Remove redundant exists() checks before file reads
source: None,
});
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't handle deflate. I think we can support later, not blocker.

@XiaoHongbo-Hope
Copy link
Copy Markdown
Contributor

+1

Copy link
Copy Markdown
Contributor

@luoyuxia luoyuxia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a quick review for this pr. Not found any blocking problem. A nice idea to optimize. LGTM!

@JingsongLi JingsongLi merged commit 553e4a3 into apache:main Apr 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants