Skip to content

feat(table): decode and validate unified fragment reuse history - #9067

Open
LuQQiu wants to merge 1 commit into
mainfrom
lu/fri-reader
Open

LuQQiu wants to merge 1 commit into
mainfrom
lu/fri-reader

Conversation

@LuQQiu

@LuQQiu LuQQiu commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What this adds

This PR implements one decoder for version-1 FRI history while preserving the existing version-0 representation.

FragmentReuseIndexDetails
        │
        ├── inline InlineContent
        └── external InlineContent bytes
                    │
                    ▼
        decode legacy_versions[] and transitions[]
                    │
                    ▼
          validate and order fragment lineage
                    │
                    ▼
               FragReuseLedger

Legacy Version.groups are lifted in memory into ordered-compaction transitions. Version-1 transitions decode their explicit mapping type:

  • Ordered compaction reuses the existing RowAddrRemap.
  • Stable partition retains its row-map reference for the dataset reader to open later.

The outer inline/external envelope is decoded through the same entry point, including external offset and size validation. Unsupported FRI index versions return an upgrade error.

Lineage validation

The decoder validates fragment digests and mapping-specific row-count invariants, then builds producer and consumer lookups for fragment IDs. It rejects duplicate producers, duplicate consumers, and cycles before returning transitions in deterministic topological order.

A transition with an unknown mapping is excluded from the readable lineage and marks the history as partially unsupported. This lets readers fall back to scanning affected paths while allowing writers and maintenance operations to reject a history they cannot preserve safely.

Mapping reuse

Each supported transition receives an in-memory content fingerprint derived from its ordered source and destination digests plus its mapping contents. The fingerprint is not persisted. It allows later reader layers to reuse an unchanged mapping reader when the FRI entry UUID changes because another transition was appended or removed.

This PR only decodes and validates history. It performs no stable-partition row-map IO, dataset lineage traversal, coverage planning, or index loading. The legacy version-0 reader and writer remain unchanged.

Validation

Tests cover inline and external histories, legacy lifting, mixed ordered-compaction and stable-partition transitions, multi-step lineage, deterministic ordering, invalid digests and row counts, duplicate producers and consumers, cycles, malformed protobuf input, unsupported mappings and index versions, external-size validation, and mapping fingerprint stability.

Validated with workspace Clippy and cargo fmt --all.

@github-actions github-actions Bot added the enhancement New feature or request label Sep 8, 2026
@LuQQiu
LuQQiu removed this pull request from stack #9066 September 9, 2026 19:15
@LuQQiu
LuQQiu added this pull request to stack #9108 September 9, 2026 19:16
@LuQQiu
LuQQiu removed this pull request from stack #9108 September 10, 2026 03:15
@LuQQiu
LuQQiu added this pull request to stack #9117 September 10, 2026 03:15
@github-actions github-actions Bot added A-python Python bindings A-deps Dependency updates A-format On-disk format: protos and format spec docs format-change A change to the format spec, which requires a vote. Remove if minor (e.g. fixing typo). labels Sep 10, 2026
@LuQQiu
LuQQiu removed this pull request from stack #9117 September 10, 2026 18:17
@LuQQiu
LuQQiu changed the base branch from lu/fri-format to lu/fri-row-map September 10, 2026 18:17
@LuQQiu
LuQQiu added this pull request to stack #9137 September 10, 2026 18:17
@LuQQiu
LuQQiu marked this pull request as ready for review September 10, 2026 18:21
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Important

Format specification vote

This PR modifies the Lance format specification, so it requires 3 binding +1 votes from PMC members (excluding the proposer) and a minimum 72-hour voting period, weekends excluded, before it can merge. Vote by approving this PR (+1) or requesting changes (−1, a veto). See the voting process.

Status: ❌ Blocked — 0 of 3 required approvals

Approvals (this commit) none (0/3)
Vetoes none
Voting period elapsed — ended Tue 2026-09-15 18:21 UTC (11:21 PDT)

Updated automatically by the format-spec vote gate, which re-checks every 15 minutes — just voted? Re-check now (press Run workflow; leave the input blank to re-check every open format PR). A PMC member may apply the format-waived label to waive the vote for a trivial edit (typo, wording, formatting).

lance-gatekeeper[bot]

This comment was marked as outdated.

@lance-gatekeeper lance-gatekeeper Bot added the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 10, 2026
LuQQiu added a commit that referenced this pull request Sep 15, 2026
FRI keeps existing indices usable after fragment rewrites by translating
old physical row addresses to new ones. Today it supports
order-preserving compaction. This proposal extends the same system index
to support stable partitioning, with both mapping types sharing one
fragment-lineage history.

Following [the unified FRI
proposal](#8972 (comment)),
source/destination lineage stays in FRI details, while large mapping
payloads remain in separate immutable files.

### One history, multiple mappings

Continue storing FRI information in a single `__lance_frag_reuse`
system-index entry. Keep the existing `InlineContent` / `ExternalFile`
envelope and the original field number for legacy versions. Add tagged
transitions alongside them:

```text
FragmentReuseIndexDetails
└── InlineContent, stored inline or in external details.binpb
    ├── legacy_versions[]
    └── transitions[]
        ├── ordered sources[]
        ├── ordered destinations[]
        └── mapping
            ├── OrderedCompaction: surviving-row bitmap
            └── StablePartition: immutable row-map reference
```

Sources and destinations define the common rewrite graph. Each mapping
defines how to translate row offsets. Legacy groups can be read as
ordered-compaction transitions; mixed histories follow fragment lineage,
not the order of records or dataset version numbers.

### Lightweight metadata, external row maps

Ordered compaction retains its compact bitmap representation. Stable
partition assigns each physical source row a nullable `uint16`
destination label, preserving source order within each destination. A
null label means the row was deleted. A counts matrix lets readers
reconstruct destination offsets without reading all preceding labels.

Stable-partition metadata records `map_id`, `map_size_bytes`, and
optional `base_id`. The labels and counts are stored in
`_fri/<map_id>/stable_partition.lance`. Mapping identity is independent
of the FRI index UUID: updating the history rewrites its metadata, but
does not rewrite existing row-map files. The history can be opened
without loading labels; address translation reads the required blocks.

### Publication and compatibility

`AppendFragmentReuseTransitions` expresses a transition delta. Combined
atomically with a fragment rewrite, it lets the commit apply the delta
to the current history and publish destination fragments and their
mappings together. The persisted FRI details remain a snapshot of that
history.

- **Index version 0:** existing compaction format and read/write
behavior remain unchanged.
- **Index version 1:** supports legacy groups and tagged transitions in
one history.
- The first commit publishing index version 1 sets reader and writer
flag **512**. The reader flag prevents old clients from partially
interpreting the history; the writer flag prevents them from dropping
mappings during metadata maintenance. Subsequent manifests retain both
bits.

### Scope and validation

This PR contains protobuf definitions, the corresponding format
documentation, the proposed flag constant, and minimal compile adapters.
It does not enable tagged-history reads or writes. Mapping
implementations and reader integration follow in #9106#9064#9067#9068#9107.

Replaces #9065 as the standalone spec at the bottom of native stack
#9137, based on main `31d78d170`.

`cargo fmt --all` and whitespace checks pass. Clippy and tests are
blocked by dependency resolution: main requires `object_store_opendal
0.60.1`, while the crates.io index currently offers only up to 0.60.0.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@lance-gatekeeper lance-gatekeeper Bot removed the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 15, 2026
lance-gatekeeper[bot]

This comment was marked as outdated.

@lance-gatekeeper lance-gatekeeper Bot added the K-changes Latest Gatekeeper recommendation requests changes. label Sep 15, 2026
Base automatically changed from lu/fri-row-map to main September 16, 2026 19:09
@lance-gatekeeper lance-gatekeeper Bot added K-changes Latest Gatekeeper recommendation requests changes. and removed K-changes Latest Gatekeeper recommendation requests changes. labels Sep 16, 2026
@lance-gatekeeper lance-gatekeeper Bot removed the K-changes Latest Gatekeeper recommendation requests changes. label Sep 16, 2026
A metadata-only ledger that decodes FRI lineage and validates envelopes,
fragment digests, row conservation, mapping payloads, and acyclic
producer/consumer lineage on top of the finalized tagged FRI proto in main.
Pure decode/validation over lance-core and the existing generated proto; no
format-spec changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgAshYD7wVzPVdjXRuWPPs

@lance-gatekeeper lance-gatekeeper Bot left a comment

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.

Gate recommendation: approve.

The stale prerequisite stack is gone: this revision keeps the finalized FRI contract and merged mapping layer, and adds only the metadata ledger. The decoder preserves version 0 behavior, validates inline and external version 1 histories, mapping payloads, row conservation, and acyclic lineage, and leaves stable-partition row maps lazy.

@lance-gatekeeper lance-gatekeeper Bot added the K-approved Latest Gatekeeper recommendation permits acceptance. label Sep 16, 2026
@LuQQiu LuQQiu removed A-format On-disk format: protos and format spec docs format-change A change to the format spec, which requires a vote. Remove if minor (e.g. fixing typo). labels Sep 16, 2026
@LuQQiu
LuQQiu requested review from jackye1995 and wkalt September 16, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-deps Dependency updates A-python Python bindings enhancement New feature or request K-approved Latest Gatekeeper recommendation permits acceptance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant