apache / apache/iceberg

Spark: Backport Hilbert-curve sort clustering to Spark 4.0 and 3.5

Open
#17,805 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
9.2k
Forks
3.5k
Avg merge
2d 11h
Merged PRs (30d)
132

Description

## Description

Hilbert-curve ordering for `rewriteDataFiles` compaction is currently
implemented only for **Spark 4.1**. The shared building blocks already live
in the version-agnostic `core` module, so the remaining work is to port the
Spark integration to the still-supported **Spark 4.0** and **Spark 3.5**
modules to keep feature parity across Spark versions.

Hilbert ordering, like Z-order, is an engine-side compaction strategy: it
sorts data files along a space-filling curve for better multi-column data
locality. It is **not** persisted in table metadata, so this is purely an
engine-integration backport with no table-format or format-version impact.

## Current state

Already present and shared (no change needed):
- `core`: `org.apache.iceberg.expressions.Hilbert` (the `Term`)
- `core`: `org.apache.iceberg.util.HilbertByteUtils`

Implemented only in Spark 4.1:
- New: `spark/v4.1/.../actions/SparkHilbertUDF.java`
- New: `spark/v4.1/.../actions/SparkHilbertFileRewriteRunner.java`
- Wired: `spark/v4.1/.../actions/RewriteDataFilesSparkAction.java`
- Wired: `spark/v4.1/.../Spark3Util.java` (parses the `hilbert(...)` sort transform)
- Wired: `spark/v4.1/.../procedures/RewriteDataFilesProcedure.java`
(accepts Hilbert sort expressions; rejects mixing Hilbert with Z-order or
identity sort columns)

Missing in Spark 4.0 and 3.5:
- `grep -r Hilbert spark/v4.0/spark/src/main` → 0 references
- `grep -r Hilbert spark/v3.5/spark/src/main` → 0 references

## Scope of work

For each of `spark/v4.0` and `spark/v3.5`:
1. Port `SparkHilbertUDF` and `SparkHilbertFileRewriteRunner`.
2. Wire `Spark3Util` to parse the `hilbert(...)` transform.
3. Wire `RewriteDataFilesSparkAction` to select the Hilbert runner.
4. Wire `RewriteDataFilesProcedure` to accept Hilbert sort expressions and
keep the existing guardrails (no mixing with Z-order / identity columns).
5. Port the corresponding tests (e.g. the Hilbert cases in
`TestRewriteDataFilesAction` and any Hilbert-specific unit tests).

## Notes / considerations

- Watch for Spark-version API differences (Scala 2.12 vs 2.13 for 3.5;
Connector/Catalyst API drift between 3.5, 4.0, 4.1). The UDF and runner
should port with minimal changes since the heavy lifting is in `core`.
- No format-version gating is required: Hilbert leaves no trace in table
metadata, so old readers/writers are unaffected.
- Keep behavior identical across versions; add tests that assert equivalence
of the produced ordering against the shared `HilbertByteUtils` reference,
mirroring the Z-order test pattern.

## Acceptance criteria

- Hilbert compaction usable from `rewriteDataFiles` action and the
`rewrite_data_files` SQL procedure on Spark 4.0 and 3.5.
- Parity tests pass on all three Spark versions.
- No changes to `core` or table-format spec.

---
*AI Disclosure: this issue was drafted with Claude Opus 4.6 (Claude Code) and reviewed by a human before filing.*

Follow-up of https://github.com/apache/iceberg/pull/16827

Contributor guide

Open the contributing guide

Research direction

Compare the Spark 4.1 implementations of SparkHilbertUDF, SparkHilbertFileRewriteRunner, Spark3Util, RewriteDataFilesSparkAction, and RewriteDataFilesProcedure with their Spark 4.0 and 3.5 counterparts. Port the corresponding Hilbert cases from TestRewriteDataFilesAction and Hilbert-specific unit tests, accounting for Spark and Scala API differences. Done means rewriteDataFiles and rewrite_data_files support Hilbert ordering on both versions, parity tests pass, and core remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, scala, spark
Domain
data-engineering, distributed-systems
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.