Skip to content

[Core] Honor parallelism in generic global index builds - #1094

Merged
JingsongLi merged 1 commit into
apache:mainfrom
JingsongLi:codex/native-global-index-parallelism
Oct 10, 2026
Merged

JingsongLi merged 1 commit into
apache:mainfrom
JingsongLi:codex/native-global-index-parallelism

Conversation

@JingsongLi

Copy link
Copy Markdown
Contributor

What changes

PyPaimon's local full-text and vindex builders already support global-index.build.parallelism. Native builds currently validate this setting but prepare shards sequentially.

  • Add the option to core options with the existing default of 1.
  • Share a bounded shard scheduler between full-text and all five vindex builders.
  • Keep one reader/writer per shard, the selected snapshot, logical ranges and relative row IDs, following Java's GenericIndexTopoBuilder.BuildIndexOperator ownership model.
  • Return messages and vector timing results in shard plan order, including skipped empty shards.
  • Stop admission on the first observed error and drain started futures before cleaning private preparation outputs. Preserve the original error and retain files already handed to callers or submitted for commit.

No new dependency or public builder API is required. Shard concurrency and each writer's native worker threads are separate controls; the default remains sequential.

Tests

  • Deterministic scheduler gates check bounded admission, actual overlap, out-of-order completion, sequential behavior, empty outputs, error/panic draining, original error causes, and private/external output ownership.
  • Real writers compare serial and parallel metadata and deterministic vector bytes for all six families, query the resulting indexes, exercise incremental coverage, and retain caller outputs when another preparation fails.
  • cargo test -p paimon --features fulltext --lib index_build --no-fail-fast: 159 passed, 2 existing ignored.
  • cargo test --locked -p paimon --lib global_index_build --no-fail-fast: 63 passed, 1 existing ignored.
  • cargo +1.98.0 clippy --locked -p paimon -p pypaimon_rust --all-targets --features paimon/fulltext -- -D warnings: passed.
  • Rust formatting and whitespace checks: passed.
  • Built the Python extension and tested it with the accompanying PyPaimon changes: 253 REST/native index tests passed; 94 targeted tests with every Native CI switch enabled passed. Both Python and native committers consumed the prepared files.

@leaves12138 leaves12138 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed 25183209 together with apache/paimon#10490 at 06e96806. No blocking findings.

The shared scheduler bounds admitted shards, keeps a separate reader/writer per shard and returns messages/timings in plan order despite out-of-order completion and empty outputs. On the first observed error it stops admission, drains started work, then aborts only this preparation's private messages while preserving the original cause. Snapshot selection, sparse relative IDs, logical coverage, external placement and caller/commit ownership remain unchanged. This matches Java's per-shard BuildIndexOperator ownership model.

Independent validation with Rust 1.94.1, Python 3.10, PyArrow 19.0.1 and a freshly rebuilt extension:

  • Core with full-text enabled: 4,027 passed, 6 existing ignores; cargo fmt passed.
  • Related filtered runs: parallel 21 passed; preparation 15 passed, overlapping the full-core run.
  • DataFusion index procedures: 27 passed.
  • Python bindings: 417 passed with the existing Native-generated smoke warehouse.
  • Paired REST/index-build suites: 291 passed and 19 subtests passed; 85 Native plans exercised.
  • All five Native CI switches enabled: 94 targeted tests passed, exercising 45 plans, 15 reads, 10 writes, 55 commits and all six tracked native update operation kinds.
  • Additional reviewer tests: 40 passed for simultaneous successful/failing builds in both internal and external directories, typed table-copy controls, explicit None/default overrides and non-finite controls rejected before output. A failing preparation did not remove the concurrent successful preparation's files.

Deterministic scheduler gates covered actual overlap, bounded admission, out-of-order completion, sequential/empty cases, error/panic draining and original causes. Real writers covered all six families, serial/parallel metadata, deterministic vector bytes, search results and incremental coverage.

Scope: Java comparison covers source-level writer/snapshot/row-ID/ownership semantics, not a Java engine or production-storage interoperability run. The local global-index.build.parallelism option/default follows existing PyPaimon; it is distinct from Java's distributed global-index.build.max-parallelism control. No production throughput or memory-scaling benchmark was performed.

@JingsongLi
JingsongLi merged commit 6d3981f into apache:main Oct 10, 2026
16 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.

2 participants