Skip to content

Range index integration: design doc + prototype#1613

Draft
badrishc wants to merge 66 commits intodevfrom
badrishc/bf-tree-integration-plan
Draft

Range index integration: design doc + prototype#1613
badrishc wants to merge 66 commits intodevfrom
badrishc/bf-tree-integration-plan

Conversation

@badrishc
Copy link
Copy Markdown
Collaborator

@badrishc badrishc commented Mar 6, 2026

No description provided.

Copy link
Copy Markdown
Contributor

@kevin-montrose kevin-montrose left a comment

Choose a reason for hiding this comment

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

Generally looks good to me - couple questions to poke at, but no blockers that I see.

@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from 320af88 to 90fbe55 Compare March 30, 2026 21:47
badrishc and others added 4 commits April 8, 2026 17:40
Resolves conflicts in IGarnetApi.cs, FunctionsState.cs, RMWMethods.cs,
and VarLenInputMethods.cs — keeps both RangeIndex and VectorSet additions.
Removes duplicate ReadOptimizedLock.cs (dev canonical version in
Synchronization/ subdirectory). Updates global.json to match installed SDK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
VectorSet implementation has been merged to dev. Update all
vectorApiPoC-storeV2 references to dev, remove 'prototype' language,
update ReadOptimizedLock note (now in libs/common/Synchronization/).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move RangeIndexManager creation to GarnetServer.CreateDatabase (before store)
and pass it through GarnetRecordDisposer and GarnetDatabase, so the disposer's
struct copies in readonly fields all share the same manager reference.

GarnetRecordDisposer:
- Holds RangeIndexManager reference (survives struct copy into readonly fields)
- DisposeOnPageEviction=true when manager is set
- DisposeRecord frees native BfTree memory on page eviction via
  DisposeTreeIfOwned, which unregisters and disposes the tree if the handle
  is valid and belongs to this process instance

RangeIndexManager.Index:
- ClearTreeHandle: zeros handle in a stub span
- DisposeTreeIfOwned: unregisters and disposes BfTree if owned

PostCopyUpdater clears old record's TreeHandle after CAS succeeds, so
eviction of the old page sees handle=0 and skips disposal. This avoids
double-free (new record owns the tree) and is safe against CAS failure
(handle is only cleared after CAS succeeds).

Tests: 4 new eviction tests verifying BfTree eviction doesn't crash,
delete+eviction works, multiple indexes freed cleanly, and
create/delete/recreate cycles under memory pressure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from f9c6697 to 62c9a13 Compare April 10, 2026 16:42
badrishc and others added 6 commits April 10, 2026 10:06
- RISetInvalidKVFieldTooLongTest: field exceeding MAXKEYLEN returns error
- RISetInvalidKVValueTooLongTest: value exceeding MAXRECORD returns error
- RISetInvalidKVRecordTooSmallTest: record below MINRECORD returns error
- RIConcurrentMultiClientTest: 8 clients x 50 ops across write/read/mixed phases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NeedCopyUpdate returns false for RICREATE, so CopyUpdater and
PostCopyUpdater are never reached. Replace the stub-copy logic
with a throw and remove the dead PostCopyUpdater ClearTreeHandle call.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cherry-pick delete-dispose-infra (storeFunctions.DisposeRecord in
InternalDelete) and apply BfTree-specific changes:

- Remove manual BfTree cleanup from MainStore and UnifiedStore
  InPlaceDeleters — now handled by GarnetRecordDisposer.DisposeRecord
  which is called by Tsavorite for both mutable and immutable deletes
- Expand GarnetRecordDisposer to accept both RangeIndexManager and
  CacheSizeTrackerHolder
- Add tests verifying DEL on BfTree keys in both mutable and
  read-only regions frees native resources immediately

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Centralize record disposal at delete/expiration sites:

- hlog.DisposeRecord(Deleted) now calls storeFunctions.DisposeRecord
  before ClearHeapFields, giving the application a single callback for
  cache-size tracking, BfTree cleanup, etc.

- InternalDelete: single DisposeRecord(Deleted) immediately after
  InPlaceDeleter (mutable) and before Seal (tombstone). Remove the
  separate else-branch DisposeRecord.

- HandleRecordElision: remove all DisposeRecord calls — record is
  already cleaned at the delete site before elision/freelist logic.

- TryTransferToFreeList: remove DisposeRecord(RevivFreeList) — record
  already cleaned.

- InternalRMW: add DisposeRecord(Deleted) for ExpireAndStop and
  ExpireAndResume at their respective sites. Replace direct
  ClearValueIfHeap(CopyUpdated) calls with DisposeRecord(CopyUpdated).

- Remove all manual heap disposal (AddHeapSize, DisposeValueObject,
  ClearValueIfHeap) from Garnet InPlaceDeleter and RMW expiration
  paths in ObjectStore and UnifiedStore session functions.

- GarnetRecordDisposer.DisposeRecord handles heap-size tracking only
  for DisposeReason.Deleted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cherry-pick delete-dispose-infra and apply BfTree-specific changes:

- Remove manual BfTree cleanup from MainStore and UnifiedStore
  InPlaceDeleters — now handled by GarnetRecordDisposer.DisposeRecord
  which is called by Tsavorite's DisposeRecord(Deleted) at the delete site
- Expand GarnetRecordDisposer to accept both RangeIndexManager and
  CacheSizeTrackerHolder
- Add tests verifying DEL on BfTree keys in both mutable and
  read-only regions frees native resources immediately

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from 19524d3 to 8ab0283 Compare April 11, 2026 01:15
@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from e8a2e1f to e1baf64 Compare April 11, 2026 01:46
Centralize record disposal at delete/expiration sites:

- hlog.DisposeRecord(Deleted) now calls storeFunctions.DisposeRecord
  before ClearHeapFields, giving the application a single callback for
  cache-size tracking, BfTree cleanup, etc.

- InternalDelete: single DisposeRecord(Deleted) immediately after
  InPlaceDeleter (mutable) and before Seal (tombstone). Remove the
  separate else-branch DisposeRecord.

- HandleRecordElision: remove all DisposeRecord calls — record is
  already cleaned at the delete site before elision/freelist logic.

- TryTransferToFreeList: remove DisposeRecord(RevivFreeList) — record
  already cleaned.

- InternalRMW: add DisposeRecord(Deleted) for ExpireAndStop and
  ExpireAndResume at their respective sites. Replace direct
  ClearValueIfHeap(CopyUpdated) calls with DisposeRecord(CopyUpdated).

- Remove all manual heap disposal (AddHeapSize, DisposeValueObject,
  ClearValueIfHeap) from Garnet InPlaceDeleter and RMW expiration
  paths in ObjectStore and UnifiedStore session functions.

- GarnetRecordDisposer.DisposeRecord handles heap-size tracking only
  for DisposeReason.Deleted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from e1baf64 to 5694911 Compare April 11, 2026 02:06
badrishc and others added 2 commits April 10, 2026 19:26
DisposeRecord(CopyUpdated) calls ClearHeapFields with clearKey=true
(since reason != Deleted), which clears overflow keys on source records
that may still be in-chain. Revert to the original ClearValueIfHeap
pattern which only clears the value, preserving keys for traceback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ObjectAllocatorImpl.DisposeRecordsInRangeForEviction: skip tombstoned
  records — they were already disposed with DisposeReason.Deleted at
  the delete site.
- GarnetRecordDisposer: BfTree disposal explicitly gated on Deleted
  and PageEviction reasons. Non-deleted evicted BfTree records are
  freed on eviction; deleted ones were already freed at delete time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@badrishc badrishc force-pushed the badrishc/bf-tree-integration-plan branch from 13d1e89 to 40df5a4 Compare April 11, 2026 23:29
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