Skip to content

Add Support for RangeIndex Diskbased Replication#1807

Open
vazois wants to merge 14 commits into
mainfrom
vazois/rindex-diskbased-replication
Open

Add Support for RangeIndex Diskbased Replication#1807
vazois wants to merge 14 commits into
mainfrom
vazois/rindex-diskbased-replication

Conversation

@vazois
Copy link
Copy Markdown
Contributor

@vazois vazois commented May 18, 2026

Summary

Adds support for shipping RangeIndex (BfTree) files during disk-based cluster replication, so replicas can fully recreate range index state after checkpoint recovery.

Work Items

  • Validate flush cleanup safety
  • Replica-side flush.bftree cleanup on resync
  • Add CheckpointFileType entries (STORE_RANGEINDEX_FLUSH, STORE_RANGEINDEX_SNAPSHOT)
  • Implement RangeIndex data source (RangeIndexFileDataSource)
  • Implement RangeIndex transmit source (RangeIndexFileTransmitSource)
  • Implement RangeIndexSnapshotReader
  • Implement RangeIndex data sink (RangeIndexFileDataSink)
  • Integrate into ReceiveCheckpointHandler
  • Integrate into ReplicaSyncSession
  • Implement replication tests

Changes

Primary Side (Sender)

  • File enumeration: RangeIndexManager.EnumerateFilesForReplication() yields all flush and snapshot .bftree files for a given checkpoint
  • Data source: RangeIndexFileDataSource — FileStream-based chunked reader with GetMetadata() for binary serialization of keyHash + address
  • Transmit source: RangeIndexFileTransmitSource — sends metadata header (startAddress=-1) then streams file content in 128KB chunks
  • Snapshot reader: RangeIndexSnapshotReader — ISnapshotReader that enumerates RI files and yields transmit sources
  • Session integration: ReplicaSyncSession.SendCheckpointAsync adds RangeIndexSnapshotReader to the transmission driver when EnableRangeIndexPreview is set

Replica Side (Receiver)

  • Data sink: RangeIndexFileDataSink with FromMetadata() factory — zero-copy deserialization from metadata span, derives target path via RangeIndexManager helpers, writes chunks via FileStream
  • Handler integration: ReceiveCheckpointHandler.ProcessSnapshotData handles RI metadata headers and file segments

Shared Infrastructure

  • CheckpointFileType enum: Added STORE_RANGEINDEX_FLUSH=7, STORE_RANGEINDEX_SNAPSHOT=8
  • Visibility: Made LogFlushPath, CheckpointSnapshotPath, rangeIndexManager public for cross-assembly access

Wire Protocol

Each RI file is transmitted as:

  1. Header (startAddress=-1): binary metadata — keyHash (32B ASCII) + address (8B LE for flush)
  2. Content chunks (startAddress=offset): raw file data in 128KB chunks
  3. End marker (empty data): signals completion

@vazois vazois changed the title Add RangeIndex file enumeration for disk-based replication Add Support for RangeIndex Diskbased Replication May 18, 2026
@vazois vazois force-pushed the vazois/rindex-diskbased-replication branch 2 times, most recently from a5d1834 to 8c40b4c Compare May 19, 2026 18:35
@vazois vazois marked this pull request as ready for review May 19, 2026 21:53
Copilot AI review requested due to automatic review settings May 19, 2026 21:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds disk-based replication support for RangeIndex (BfTree) files so replicas can restore RangeIndex state after checkpoint recovery.

Changes:

  • Add replication plumbing for RangeIndex flush/snapshot .bftree files (enumeration, reader, transmit source, receiver sink, handler integration).
  • Update server gating: allow RangeIndex preview in cluster mode except for diskless replication.
  • Add a new cluster test project and plumb enableRangeIndexPreview through test helpers/context.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
test/standalone/Garnet.test/TestUtils.cs Adds enableRangeIndexPreview parameter forwarding for test server options.
test/cluster/Garnet.test.cluster/ClusterTestContext.cs Adds enableRangeIndexPreview option to cluster test instance creation paths.
test/cluster/Garnet.test.cluster.replication.rangeindex/Garnet.test.cluster.replication.rangeindex.csproj Introduces a new test project for RangeIndex replication scenarios.
test/cluster/Garnet.test.cluster.replication.rangeindex/ClusterRangeIndexReplicationTests.cs Adds end-to-end cluster replication tests for RangeIndex behavior.
libs/server/StoreWrapper.cs Exposes rangeIndexManager for cross-assembly replication usage.
libs/server/Resp/RangeIndex/RangeIndexManager.cs Adds RI file enumeration helpers and replication file listing API.
libs/host/GarnetServer.cs Updates validation to disallow RI preview only in diskless replication mode.
libs/cluster/Server/Replication/ReplicaOps/DiskbasedReplication/ReceiveCheckpointHandler.cs Adds handling to create RI sinks from metadata headers.
libs/cluster/Server/Replication/ReplicaOps/DiskbasedReplication/RangeIndexFileDataSink.cs Implements replica-side sink that writes received RI file bytes to disk.
libs/cluster/Server/Replication/PrimaryOps/DiskbasedReplication/ReplicaSyncSession.cs Adds RangeIndexSnapshotReader to checkpoint transmission when RI preview enabled.
libs/cluster/Server/Replication/PrimaryOps/DiskbasedReplication/RangeIndexSnapshotReader.cs Enumerates RI files for a checkpoint and yields transmit sources.
libs/cluster/Server/Replication/PrimaryOps/DiskbasedReplication/RangeIndexFileTransmitSource.cs Sends RI metadata header + chunked file bytes + end marker over snapshot protocol.
libs/cluster/Server/Replication/PrimaryOps/DiskbasedReplication/RangeIndexFileDataSource.cs Implements FileStream-backed chunk reader plus metadata generation for RI files.
libs/cluster/Server/Replication/CheckpointFileType.cs Adds two new CheckpointFileType values for RI flush/snapshot files.
Garnet.slnx Adds the new RangeIndex replication test project to the solution.

Comment thread libs/server/Resp/RangeIndex/RangeIndexManager.cs Outdated
Comment thread libs/server/StoreWrapper.cs Outdated
@vazois vazois force-pushed the vazois/rindex-diskbased-replication branch from 986b212 to 81861f8 Compare May 20, 2026 17:40
@vazois vazois requested a review from tiagonapoli May 21, 2026 17:33
@vazois vazois force-pushed the vazois/rindex-diskbased-replication branch from 81861f8 to ec87222 Compare May 21, 2026 17:35
Comment thread libs/server/StoreWrapper.cs Outdated
/// RangeIndex (BfTree) manager shared across sessions
/// </summary>
internal readonly RangeIndexManager rangeIndexManager;
public readonly RangeIndexManager rangeIndexManager;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why does this need to become public?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Need to pass it down to ClusterProvider through the storeWrapper instance so it can be used during shipping snapshot during full sync.
I can possible pass the RangeIndexManager instance directly in the ClusterProvider.
Other fields in StoreWrapper are public (i.e. appendOnlyFile, store etc.), though they are accessed as a property.

@vazois vazois force-pushed the vazois/rindex-diskbased-replication branch from dfcf37e to ec87222 Compare May 22, 2026 23:39
vazois and others added 14 commits May 22, 2026 17:06
Add EnumerateFilesForReplication() to RangeIndexManager that lists all
flush.bftree and checkpoint snapshot files needed for a given checkpoint
token and hlog address range. Refactor flush file parsing into a shared
EnumerateFlushFiles() helper used by both OnTruncateImpl and the new
replication enumeration method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nsmit

Implement the primary-side pipeline for shipping RangeIndex files during
disk-based replication:

- Add STORE_RANGEINDEX_FLUSH (7) and STORE_RANGEINDEX_SNAPSHOT (8) to
  CheckpointFileType enum
- RangeIndexFileDataSource: FileStream-based ISnapshotDataSource for
  chunked reading of .bftree files
- RangeIndexFileTransmitSource: sends metadata header (keyHash + address
  as binary, startAddress=-1) then streams file content in chunks
- RangeIndexSnapshotReader: ISnapshotReader that enumerates RI files via
  EnumerateFilesForReplication and yields transmit sources
- Make RangeIndexFileEntry, EnumerateFilesForReplication, and RiLogRoot
  public for cross-project access

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add RangeIndexFileDataSink with FromMetadata factory for zero-copy
  deserialization of metadata header directly from ReadOnlySpan
- Integrate RangeIndexSnapshotReader into ReplicaSyncSession.SendCheckpointAsync
  conditioned on serverOptions.EnableRangeIndexPreview
- Move GetMetadata serialization into RangeIndexFileDataSource (not interface)
- Make LogFlushPath/CheckpointSnapshotPath public, rangeIndexManager public
- Remove unused Garnet.server/System.Text usings from handler

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vazois vazois force-pushed the vazois/rindex-diskbased-replication branch from ec87222 to 8d9e5a4 Compare May 23, 2026 00:06
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