Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0a1e574
Tsavorite: add PostCopyToTail, OnTruncate triggers; OnFlush(addr); RM…
badrishc May 7, 2026
6a99a6c
RangeIndex: refactor for compaction lifecycle (Guid keying, two roots…
badrishc May 7, 2026
325187c
Tests: trigger ext tests; update RecordLifecycleTests + RangeIndex di…
badrishc May 7, 2026
313e7cc
Tests: add Defect 1 reproduction (flush files immutable) and OnTrunca…
badrishc May 7, 2026
dd91b8f
doc: update range-index-resp-api.md for compaction lifecycle integration
badrishc May 7, 2026
4252a38
RangeIndex: drop StorageBackend==Disk guard from DisposeTreeUnderLock…
badrishc May 8, 2026
0dfba3b
RangeIndex: restore xmldoc + inline comments on ComputeLeafPageSize/R…
badrishc May 8, 2026
d2c14d5
RangeIndex: simplify pre-stage paths to direct File.Copy (drop .tmp +…
badrishc May 8, 2026
4249b05
RangeIndex: fix race in PreStageAndRegisterPending — acquire per-key …
badrishc May 8, 2026
03bcdbf
RangeIndex: address GPT-5.5 PR review (3 issues; FlagTransferred, OnF…
badrishc May 8, 2026
696fa03
RangeIndex: DEL preserves per-flush snapshot files (LOG-tied lifetime)
badrishc May 8, 2026
5261ca4
RangeIndex: remove .tmp dead-code distraction
badrishc May 8, 2026
e9a3833
RangeIndex: consolidate stub flag accessors (RecordInfo style)
badrishc May 8, 2026
32e4018
RangeIndex: comment cleanup + Tsavorite format fix
badrishc May 8, 2026
3e7b7f5
ci: point setup-rust-toolchain at the bftree workspace
badrishc May 8, 2026
0977824
RangeIndex: restore per-key exclusive lock around OnFlush snapshot
badrishc May 8, 2026
baa7b40
RangeIndex: address dev-vs-PR design audit (3 findings)
badrishc May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ jobs:
uses: actions/setup-dotnet@v4
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# Garnet's only Cargo workspace is the bftree native binding; the repo root has no
# Cargo.toml, so the action's default `cache-workspaces: ". -> target"` causes
# rust-cache's `cargo metadata` to fail with "could not find Cargo.toml" (exit 101).
cache-workspaces: libs/native/bftree-garnet
- name: Install dependencies
run: dotnet restore
- name: Build Garnet
Expand Down
17 changes: 15 additions & 2 deletions libs/host/GarnetServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,21 @@ private GarnetDatabase CreateDatabase(int dbId, GarnetServerOptions serverOption
CustomCommandManager customCommandManager)
{
var removeOutdated = !serverOptions.EnableCluster;
var rangeIndexDataDir = Path.Combine(serverOptions.CheckpointBaseDirectory, GarnetServerOptions.GetCheckpointDirectoryName(dbId));
var rangeIndexManager = new RangeIndexManager(serverOptions.EnableRangeIndexPreview, rangeIndexDataDir,

// Two-roots layout for RangeIndex files:
// riLogRoot — log-tied (working file + per-flush snapshots), co-located with hlog.
// Falls back through LogDir → CheckpointDir → cwd, mirroring Tsavorite's
// CheckpointBaseDirectory chain so RangeIndex works without storage tier.
// cprDir — checkpoint-tied (per-token snapshots live under <token>/rangeindex/),
// alongside Tsavorite's cpr-checkpoints/<token>/info.dat etc.
var logRootBase = serverOptions.LogDir
?? serverOptions.CheckpointDir
?? Directory.GetCurrentDirectory();
var riLogRoot = Path.Combine(logRootBase ?? string.Empty, "Store", "rangeindex");
var cprDir = Path.Combine(serverOptions.GetStoreCheckpointDirectory(dbId), "cpr-checkpoints");

var rangeIndexManager = new RangeIndexManager(serverOptions.EnableRangeIndexPreview,
riLogRoot: riLogRoot, cprDir: cprDir,
removeOutdatedCheckpoints: removeOutdated, loggerFactory?.CreateLogger("RangeIndexManager"));
var store = CreateStore(dbId, clusterFactory, customCommandManager, storeEpoch, rangeIndexManager, out var stateMachineDriver, out var sizeTracker, out var kvSettings);
var aof = CreateAOF(dbId);
Expand Down
30 changes: 29 additions & 1 deletion libs/native/bftree-garnet/BfTreeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,35 @@ public void Snapshot(string snapshotPath = null)
}

/// <summary>
/// Snapshot the BfTree to a specified target file for flush persistence.
/// Snapshot a disk-backed BfTree to a target file, given only its native handle (no managed wrapper).
/// Used by RangeIndex's <c>OnFlush</c> path which has direct access to the stub's TreeHandle but not
/// the managed <see cref="BfTreeService"/> instance.
/// <para>Mirrors instance <see cref="SnapshotToFile"/>: invokes <c>bftree_snapshot(handle)</c> to drain
/// the circular buffer to the data file, then <c>System.IO.File.Copy</c> from
/// <paramref name="dataPath"/> to <paramref name="targetPath"/>.</para>
/// </summary>
/// <param name="handle">Native BfTree pointer (from the stub's <c>TreeHandle</c>).</param>
/// <param name="dataPath">Path of the live working file used by the BfTree
/// (e.g. <c>{root}/&lt;hash&gt;.data.bftree</c>).</param>
/// <param name="targetPath">Destination path for the snapshot copy.</param>
public static void SnapshotToFileByPtr(nint handle, string dataPath, string targetPath)
{
if (handle == nint.Zero)
throw new ArgumentException("Native handle is null.", nameof(handle));
if (string.IsNullOrEmpty(dataPath))
throw new ArgumentException("dataPath is required.", nameof(dataPath));
if (string.IsNullOrEmpty(targetPath))
throw new ArgumentException("targetPath is required.", nameof(targetPath));

int result = NativeBfTreeMethods.bftree_snapshot(handle);
if (result != 0)
throw new InvalidOperationException("Failed to snapshot disk-backed BfTree before file copy.");

System.IO.File.Copy(dataPath, targetPath, overwrite: true);
}
Comment on lines +515 to +529

/// <summary>
/// Snapshot a BfTree to a specified target file for flush persistence.
/// For disk-backed trees: performs in-place snapshot, then copies the data file to <paramref name="targetPath"/>.
/// For memory-only trees: serializes directly to <paramref name="targetPath"/>.
/// </summary>
Expand Down
Loading
Loading