Skip to content

B-Prod-P2: FrsSnapshot + MVCC linker bindings (depends on P1 + ForSt P2)#2

Open
jackylee-ch wants to merge 1 commit into
b-prod-p1-keygroup-cfrouterfrom
b-prod-p2-mvcc-ffi
Open

B-Prod-P2: FrsSnapshot + MVCC linker bindings (depends on P1 + ForSt P2)#2
jackylee-ch wants to merge 1 commit into
b-prod-p1-keygroup-cfrouterfrom
b-prod-p2-mvcc-ffi

Conversation

@jackylee-ch

Copy link
Copy Markdown
Owner

Summary

Per spec §10.0 / §10a / §10b. Depends on ForSt P2 (Rust FFI exports) and P1 (Flink keyed-backend skeleton).

This PR ships the JDK 25 FFM Java bindings for the new MVCC + incremental-checkpoint surface that ForSt P2 added.

Tasks 2.5-2.6 covered

  • 2.5 `FrsSnapshot` AutoCloseable wrapper + `ForStRsLinker.dbSnapshot` / `dbReleaseSnapshot` bindings + 4 unit tests (round-trip, double-close-safe, try-with-resources, post-close handle access throws)
  • 2.6 Linker bindings: `getAt`, `iteratorOpenAt`, `createIncrementalCheckpointAt`, `dbIncrementalCheckpointResultFree`, `dbOpenFromIncremental` + 2 extended tests (snapshot isolation across FFM hop; iter_at filters by snapshot.seq)

Bundled into a single commit because the linker bindings for 2.5 and 2.6 are interleaved in `ForStRsLinker.java` (single MethodHandle field section + single constructor binding block) and splitting would fragment the §8 module surface.

Test plan

  • `mvn test -pl flink-state-backends/flink-statebackend-forst-rs` — all 81 tests pass (75 prior + 4 new `FrsSnapshotTest` + 2 new extended)
  • cdylib loaded via `forstrs.native.libpath` system property (JDK 25, FFM `Linker.Option.critical(true)` for `getAt`)
  • CI runs the same stack on Linux

🤖 Generated with Claude Code

…nker bindings

Task 2.5 — FrsSnapshot Java type
  * `FrsSnapshot` AutoCloseable wrapper over the native FrsSnapshot
    pointer; `close()` is idempotent (per spec §10.0 ABI lifetime
    contract); `handle()` throws IllegalStateException after close so
    use-after-close fails fast on the Java side rather than corrupting
    the native registry.
  * `ForStRsLinker.dbSnapshot(db, arena)` mints a snapshot;
    `ForStRsLinker.dbReleaseSnapshot(db, snapshot)` is package-private
    and routed through `FrsSnapshot.close()` so callers always go through
    the AutoCloseable contract.
  * 4 unit tests in `FrsSnapshotTest`: round-trip, double-close-safe,
    try-with-resources release, post-close handle access throws.

Task 2.6 — Linker bindings for getAt / iteratorOpenAt / incremental ckpt
  * `getAt(db, cf, snapshot, key)` — versioned point-lookup; bound
    critical-mode like `get` for hot-path zero-copy. Returns null on
    NOT_FOUND.
  * `iteratorOpenAt(db, cf, snapshot, arena)` — versioned forward
    iterator that yields the latest version of each user-key with
    seq <= snapshot.seq.
  * `createIncrementalCheckpointAt(db, snapshot, ckptId, baseId, resultPtr)`
    + `dbIncrementalCheckpointResultFree(resultPtr)` — caller stages the
    32-byte FrsIncrementalCheckpointResult struct in their own arena
    and frees the inner allocations via the dedicated free helper.
  * `dbOpenFromIncremental(arena, targetDir, baseManifest, sstFiles)`
    — restore-side counterpart that builds the per-call C-string array
    in a confined arena.
  * 2 new tests in `ForStRsLinkerExtendedTest`:
    `snapshotIsolationAcrossFfmHop` (write v1 → snapshot → write v2;
    getAt sees v1 while normal get sees v2) and
    `iteratorOpenAtFiltersBySnapshotSeq` (3 keys before snapshot + 1
    after; iter yields exactly the 3 pre-snapshot keys).

Combined into a single commit because the linker bindings for 2.5 and
2.6 are interleaved in `ForStRsLinker.java` (single MethodHandle field
section + single constructor binding block) and splitting would
fragment the §8 module surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant