Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
308 commits
Select commit Hold shift + click to select a range
056d505
address feedback; switch to manualresetevent for waits instead of spi…
kevin-montrose Sep 24, 2025
bc9e503
merge main
kevin-montrose Sep 24, 2025
56b5639
checking attribute validation logic against Redis (there isn't any...…
kevin-montrose Sep 25, 2025
9573347
sketch out WITHATTRIBS support for VSIM
kevin-montrose Sep 26, 2025
2b6a3d7
fixup VSIM WITHATTRIBS, some locking stuff to be figured out
kevin-montrose Sep 26, 2025
4483c7d
match Redis error messages
kevin-montrose Sep 26, 2025
90ae2ab
match Redis error messages
kevin-montrose Sep 26, 2025
eab7343
log around replication task failures
kevin-montrose Sep 26, 2025
55641db
test more combinations for replication
kevin-montrose Sep 27, 2025
340f74d
more logging around vector set operation failures
kevin-montrose Sep 27, 2025
11345f4
Merge branch 'main' into vectorApiPoC
kevin-montrose Sep 27, 2025
8f8828d
expand tests to validate more attributes
kevin-montrose Sep 29, 2025
99fab5b
fixup some FFI stuff, including validating that K <= L (ie. COUNT <= EF)
kevin-montrose Sep 29, 2025
9459f81
update diskann-garnet; remove copies when accepting XB8 inputs
kevin-montrose Oct 1, 2025
f7e5e72
remove copies when preparing keys
kevin-montrose Oct 1, 2025
4d91cb7
remove the fiction that we're going to use anything but DiskANN for a…
kevin-montrose Oct 1, 2025
6ce6171
support multiple return vector formats so DiskANN can eliminate anoth…
kevin-montrose Oct 1, 2025
07e5c9a
stopgap commit; sketch out a multi-key read_callback that both prefet…
kevin-montrose Oct 1, 2025
1d49f7e
stopgap commit: add missing file
kevin-montrose Oct 2, 2025
25846f8
stopgap commit; correctly set count
kevin-montrose Oct 6, 2025
551bdbf
stopgap commit; rework for IReadArgBatch
kevin-montrose Oct 6, 2025
efcf0f7
stopgap commit; fixup bugs with IReadArgBatch implementation
kevin-montrose Oct 6, 2025
dfec8c5
stopgap commit; correctly capture callback and callback context on Ve…
kevin-montrose Oct 6, 2025
97c53a9
small refactor to avoid extra accesses and recalcs
kevin-montrose Oct 6, 2025
f0501af
bump diskann-garnet
kevin-montrose Oct 7, 2025
1507f01
rework session tracking so we can set it high up during adds, which l…
kevin-montrose Oct 7, 2025
94e4c39
micro optimization around allocating space for vector set index reads
kevin-montrose Oct 7, 2025
24a0ef4
stopgap commit; start working on recovering indexes from disk / witho…
kevin-montrose Oct 7, 2025
d7a331f
suppress for now
kevin-montrose Oct 8, 2025
9104b92
remove temporary copies and allocations from VADD replication
kevin-montrose Oct 8, 2025
333b4e1
fix replication tests by pausing for VADDs to also catch up
kevin-montrose Oct 8, 2025
83815bb
bump diskann-garnet to 1.0.4
kevin-montrose Oct 9, 2025
ec2569d
1.0.4 has issues, rolling back to 1.0.3
kevin-montrose Oct 9, 2025
add0e44
DRY up index reading to simplify recreation and prepare for shared lo…
kevin-montrose Oct 9, 2025
bda2750
extend locking DRY'ing to replication
kevin-montrose Oct 9, 2025
45073c2
bump to 1.0.5
kevin-montrose Oct 9, 2025
66bdbf3
sketch out sharded read locks
kevin-montrose Oct 9, 2025
dc7718c
bump to 1.0.8
kevin-montrose Oct 9, 2025
6d144ac
rework replication to (probably) fix a bad pointer on passed SpanBytes
kevin-montrose Oct 10, 2025
137d39b
implement (sort of) VEMB for debugging purposes
kevin-montrose Oct 10, 2025
eb393c2
fix merge
kevin-montrose Oct 10, 2025
0aa68d1
stopgap commit; get some stopwatch based logging in for diagnostics
kevin-montrose Oct 11, 2025
e15ffb0
Revert "stopgap commit; get some stopwatch based logging in for diagn…
kevin-montrose Oct 12, 2025
bda5799
less naive prefetch approach, working in batches of 12 and only if we…
kevin-montrose Oct 12, 2025
862f3f1
JIT may not be smart enough to elide these bounds checks, so just go …
kevin-montrose Oct 12, 2025
ff8ec6d
bump diskann and garnet release version
kevin-montrose Oct 13, 2025
559bb9e
fail deadly while upstream Entra fixes are rolling out
kevin-montrose Oct 13, 2025
b8428da
memory corruption bug somewhere - kick up DiskANN in the optimistic h…
kevin-montrose Oct 14, 2025
a43d6a7
change stress amounts
kevin-montrose Oct 14, 2025
73b2122
diskann is hard assuming 75 for now, so change tests accordingly
kevin-montrose Oct 14, 2025
9389ee3
more bounds checking, more logging, let's find this corruption
kevin-montrose Oct 14, 2025
3dfc58a
sketch out VREM
kevin-montrose Oct 15, 2025
1b8a517
DRY up dimension calculation on VADD
kevin-montrose Oct 15, 2025
7856461
don't return success if delete didn't do anything
kevin-montrose Oct 15, 2025
a96efd9
tweak library resolution logic; when hosted as a service on Linux, cu…
kevin-montrose Oct 16, 2025
9fc01e1
bump version
kevin-montrose Oct 16, 2025
2682dc8
be more defensive, though shouldn't really matter; also log more on f…
kevin-montrose Oct 18, 2025
62394a0
Revert "rework replication to (probably) fix a bad pointer on passed …
kevin-montrose Oct 18, 2025
e19f77a
Revert "fix replication tests by pausing for VADDs to also catch up"
kevin-montrose Oct 18, 2025
dbf72b4
Revert "remove temporary copies and allocations from VADD replication"
kevin-montrose Oct 18, 2025
a34ecb6
after reverting replication optimizations, bump version
kevin-montrose Oct 18, 2025
5d159ae
ruled out corruption, remove all these bounds checks and other valida…
kevin-montrose Oct 20, 2025
f811d63
bump diskann-garnet; VREM implemented and VREM replication tested
kevin-montrose Oct 20, 2025
c93a36f
deleting a vector set causes its internal values to be cleanedup (ver…
kevin-montrose Oct 21, 2025
b94494b
fix DEL replays w.r.t. vector sets
kevin-montrose Oct 21, 2025
ac54543
more bits for diskann in context
kevin-montrose Oct 21, 2025
3b1b94c
diskann-garnet to .12, attributes now managed on that side
kevin-montrose Oct 21, 2025
abee408
exclude vector set data from a number of places; get most (all?) test…
kevin-montrose Oct 21, 2025
d7281e3
fixes for recovery, more tests for recovery, diskann-garnet needs som…
kevin-montrose Oct 22, 2025
81a77a5
temp hack around a re-entrancy issue
kevin-montrose Oct 23, 2025
5801363
hack harder
kevin-montrose Oct 23, 2025
b40b4b4
fix recovery test
kevin-montrose Oct 23, 2025
85e7a64
bump to .13
kevin-montrose Oct 23, 2025
f7824ae
bump diskann-garnet to fix bugs
kevin-montrose Oct 24, 2025
37f5b27
restart cleanups upon recovery
kevin-montrose Oct 24, 2025
55fa2cb
start a design doc now that we're mostly nailed down the PoC
kevin-montrose Oct 24, 2025
4a0da48
Remove dead code; we're not using multiinsert right now, and won't fo…
kevin-montrose Oct 24, 2025
133a883
remove more dead code
kevin-montrose Oct 24, 2025
365da1b
finish up first draft of vector-sets.md
kevin-montrose Oct 24, 2025
79a4720
fixup some links
kevin-montrose Oct 24, 2025
b310c5b
naturally, a typo in the first two lines
kevin-montrose Oct 24, 2025
3f192c1
formatting
kevin-montrose Oct 24, 2025
8a46d85
typos
kevin-montrose Oct 24, 2025
bb91ff4
more typos
kevin-montrose Oct 24, 2025
ec74024
note migration is still a WIP
kevin-montrose Oct 26, 2025
a58afad
remove hack from index creation
kevin-montrose Oct 27, 2025
79a4523
remove hack from index recreation
kevin-montrose Oct 27, 2025
54d648a
expand tests
kevin-montrose Oct 27, 2025
49e0aa6
merge main
kevin-montrose Oct 28, 2025
8e09458
fix tests
kevin-montrose Oct 28, 2025
0f1f627
fix tests
kevin-montrose Oct 28, 2025
f7caec2
sketch out rmw callback for DiskANN
kevin-montrose Oct 28, 2025
70e694b
don't roll version back
kevin-montrose Oct 28, 2025
ee5fbe7
fix a bunch of typos
kevin-montrose Oct 29, 2025
a5ffc57
more corrections and cleanup upon review
kevin-montrose Oct 29, 2025
f7e87d0
move VectorManager onto GarnetDatabase, preparing for multi-DB testing
kevin-montrose Oct 29, 2025
3a99f40
mention docs
kevin-montrose Oct 29, 2025
b68dbf5
implement copy-update functions, I seem to have misunderstood the poi…
kevin-montrose Oct 29, 2025
294e1b4
knock our remainder of recreate tests
kevin-montrose Oct 30, 2025
3a5d180
track hash slots with vector set metadata
kevin-montrose Oct 30, 2025
1f0b297
add (failing) basic migration test
kevin-montrose Oct 30, 2025
eb84bd7
stopgap commit; sketch out and document the migration flow
kevin-montrose Oct 30, 2025
74098e5
stopgap commit; primary -> primary for _hash slots_ works; replicas d…
kevin-montrose Oct 31, 2025
f71b4d8
stopgap commit; all Vector Set tests passing, though there's still mi…
kevin-montrose Oct 31, 2025
8f5f8de
fix tests
kevin-montrose Nov 3, 2025
cb6ee17
replicas now follow migrated primary Vector Sets; needs a lot more te…
kevin-montrose Nov 3, 2025
1f11849
migrate ... keys implemented, which wraps up migration (in theory)
kevin-montrose Nov 4, 2025
97478a1
Merge branch 'main' into vectorApiPoC
kevin-montrose Nov 4, 2025
2d9b303
fix tests; all tests passing now
kevin-montrose Nov 4, 2025
c37af2e
test moving multiple vector sets to a primary that already has vector…
kevin-montrose Nov 5, 2025
67b0180
more vector set migration tests, and fixes
kevin-montrose Nov 5, 2025
8408dc6
Rework timeouts for some cluster migration tests
kevin-montrose Nov 5, 2025
120bf69
stopgap commit; lots of hackery to try and make writes during migrati…
kevin-montrose Nov 7, 2025
9f1be80
stopgap commit; this appears to work, need to stress and remove lots …
kevin-montrose Nov 7, 2025
4b08056
stopgap commit; remove a bunch of hackery and logging
kevin-montrose Nov 7, 2025
c277e5c
stress test is still a bit flaky, but there are common non-Vector Set…
kevin-montrose Nov 7, 2025
0a902da
note blocking during migrations in vector-sets.md
kevin-montrose Nov 7, 2025
9a1eeac
restore AAD, this is long since debuged
kevin-montrose Nov 9, 2025
d10a29e
knock a number of hacks out
kevin-montrose Nov 9, 2025
a8f3708
remove another hack
kevin-montrose Nov 9, 2025
51ef75a
hide Vector Sets behind a feature flag - flag defaults on for tests, …
kevin-montrose Nov 9, 2025
f4c1508
dry up exclusive lock acquisition
kevin-montrose Nov 9, 2025
1d62b34
split VectorManager up to make easier to review
kevin-montrose Nov 9, 2025
6704cd5
knock out more todos
kevin-montrose Nov 9, 2025
7173239
cleanup after migration failures
kevin-montrose Nov 9, 2025
e398a85
this TODO is invalid
kevin-montrose Nov 9, 2025
aa6ea9e
don't bump version
kevin-montrose Nov 10, 2025
992fde8
implement ReadWithPrefetch (pulled off of vectorApiPoC work)
kevin-montrose Nov 10, 2025
c78b142
revert change to NativeStorageDevice, not needed as part of Vector Sets
kevin-montrose Nov 10, 2025
aa780f8
formatting
kevin-montrose Nov 10, 2025
a228dc8
actually bump to latest internal, rather than leaving this stashed
kevin-montrose Nov 10, 2025
b75c489
move MGET (normal and scatter-gather) onto ReadWithPrefetch
kevin-montrose Nov 12, 2025
4ab4e6b
address feedback
kevin-montrose Nov 13, 2025
69f8a24
Merge branch 'main' into readWithPrefetch
kevin-montrose Nov 14, 2025
33a8cc3
document that 4-bytes before key for RMW callback is required
kevin-montrose Nov 14, 2025
ca9d14a
move method to migration partial
kevin-montrose Nov 14, 2025
d1d9d6b
correctly update session metrics with new MGET impls
kevin-montrose Nov 14, 2025
9f22e84
Merge branch 'main' into vectorApiPoC
kevin-montrose Nov 17, 2025
c4c4d45
fix merge
kevin-montrose Nov 17, 2025
6ad3dd8
stopgap commit; sketch out alternative locking scheme to replace obje…
kevin-montrose Nov 18, 2025
26f4a86
tweaks to locking impl after some benchmarking
kevin-montrose Nov 19, 2025
c9d2db8
clarify docs, naming, and the 'why' of some optimizations in new lock…
kevin-montrose Nov 19, 2025
505916b
handle feedback; rather than process number, use a thread static whic…
kevin-montrose Nov 20, 2025
f2ee221
formatting
kevin-montrose Nov 20, 2025
e3d1682
Merge branch 'main' into vectorApiPoC
kevin-montrose Nov 20, 2025
9865327
fix merge
kevin-montrose Nov 20, 2025
4cee80c
fix website build
kevin-montrose Nov 20, 2025
a869917
address feedback; generalize vector set locks, move and rename
kevin-montrose Nov 20, 2025
151181e
bump DiskANN integration to 1.0.16 to fix Linux issue
kevin-montrose Dec 1, 2025
01edafc
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 1, 2025
6a05736
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 1, 2025
d2e139a
GH actions are hitting disk throttle issues in this test, so attempt …
kevin-montrose Dec 1, 2025
ce8cb2e
Revert "GH actions are hitting disk throttle issues in this test, so …
kevin-montrose Dec 1, 2025
1117c8f
another attempt at taking IO pressure off GH linux tests
kevin-montrose Dec 1, 2025
c855179
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 1, 2025
9a18ca6
helped some, but more explicit throttling required
kevin-montrose Dec 1, 2025
5d119d8
explicit throttling works some of the time, but still fails occasiona…
kevin-montrose Dec 2, 2025
6f88797
move off ObjectStore in preparation of retargeting PR against storev2…
kevin-montrose Dec 2, 2025
dbf02d5
Update libs/server/Storage/Session/MainStore/VectorStoreOps.cs
kevin-montrose Dec 2, 2025
99fc672
address feedback; remove dead code
kevin-montrose Dec 2, 2025
5f86c80
address feedback; correct comment, denote missing WRONGTYPE behavior
kevin-montrose Dec 2, 2025
6680864
address feedback; remove dead code
kevin-montrose Dec 2, 2025
dcfd68f
Merge branch 'vectorApiPoC' of https://github.com/microsoft/garnet in…
kevin-montrose Dec 2, 2025
f51b861
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 2, 2025
6a0521b
address feedback; remove commented out usings
kevin-montrose Dec 2, 2025
723a618
Merge branch 'vectorApiPoC' of https://github.com/microsoft/garnet in…
kevin-montrose Dec 2, 2025
6dfc10e
cleanup Vector Set dev docs
kevin-montrose Dec 3, 2025
5221139
knock out a TODO
kevin-montrose Dec 3, 2025
c8e856b
address feedback; remove dead code
kevin-montrose Dec 3, 2025
ebcba56
address feedback; fixes in migration logic around failures
kevin-montrose Dec 3, 2025
b7072d8
harden RepeatedVectorSetDeletes test; fix a math issue in the 'WRONGT…
kevin-montrose Dec 3, 2025
940eb60
wrongtype check leaving a null in some cases; wasn't possible before …
kevin-montrose Dec 3, 2025
4938e78
log more on this failure, as only happening in GH
kevin-montrose Dec 3, 2025
6ae6f76
add missing logic when outside mutable region
kevin-montrose Dec 3, 2025
0e44ab8
address feedback; some fixes around locking
kevin-montrose Dec 3, 2025
9882dc6
remove accidental using
kevin-montrose Dec 3, 2025
0384348
correctly assert; fix typo
kevin-montrose Dec 3, 2025
5178d86
rework WRONGTYPE logic
kevin-montrose Dec 4, 2025
b5f2746
deal with consequences of WRONGTYPE cleanup
kevin-montrose Dec 4, 2025
065c482
stopgap commit; start working on fixing failed deletions with a (fail…
kevin-montrose Dec 5, 2025
ba07d9e
address feedback; goto is a smell here
kevin-montrose Dec 5, 2025
aeec3d3
address feedback; add missing asserts
kevin-montrose Dec 5, 2025
e5b5e60
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 5, 2025
d4a96ea
stopgap commit; start tracking in progress deletes, not actually hand…
kevin-montrose Dec 5, 2025
9cd72c5
address feedback; DRY up and remove some unused bytes around completi…
kevin-montrose Dec 5, 2025
f4bc0ee
stopgap commit; recover partial deletes on startup, still needs testing
kevin-montrose Dec 8, 2025
942efd8
stopgap commit; fail Vector Set commands sensibly if operating on a p…
kevin-montrose Dec 8, 2025
146f053
stopgap commit; start testing partial deletion recovery scenario
kevin-montrose Dec 8, 2025
cc55f1f
stopgap commit; partial delete recovery working, needs docs and check…
kevin-montrose Dec 8, 2025
d712836
stopgap commit; delete recovery working and tested, still needs docum…
kevin-montrose Dec 8, 2025
06998f7
wrap up delete rework, update documentation
kevin-montrose Dec 9, 2025
08354ad
Merge branch 'vectorApiPoC' of https://github.com/microsoft/garnet in…
kevin-montrose Dec 9, 2025
2b4659d
merge main
kevin-montrose Dec 9, 2025
505c528
address feedback; as cluster expected DB=0 for now, add a check for it
kevin-montrose Dec 9, 2025
3ccd43c
address feedback; parameter names and docs
kevin-montrose Dec 9, 2025
efd28de
address feedback; there's a race here, fix it but this needs to be cl…
kevin-montrose Dec 9, 2025
d7fce7d
factor counting logic out into its own reusable type CountingEventSlim
kevin-montrose Dec 9, 2025
52efef0
fix formatting
kevin-montrose Dec 9, 2025
7fc8d68
fix auth test
kevin-montrose Dec 10, 2025
f12db16
address feedback; hide StoreWrapper from rest of AofProcessor
kevin-montrose Dec 10, 2025
e483621
stopgap commit; stop VectorManager background tasks if ReplicaReplayT…
kevin-montrose Dec 10, 2025
5a57e13
fix injection tests in RELEASE
kevin-montrose Dec 11, 2025
496355f
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 11, 2025
9e0e820
this is TODONE
kevin-montrose Dec 11, 2025
527da76
Merge branch 'vectorApiPoC' of https://github.com/microsoft/garnet in…
kevin-montrose Dec 11, 2025
22fe9f8
Merge branch 'main' into vectorApiPoC
kevin-montrose Dec 12, 2025
0c4eb83
address feedback; cancellation of replay task also spins down (but al…
kevin-montrose Dec 15, 2025
35f31d3
address feedback; as Tiago noted, Redis _does_ allow empty vector set…
kevin-montrose Dec 15, 2025
c3ffbcc
address flaky test
kevin-montrose Dec 15, 2025
da3d6bd
fix more test flakiness
kevin-montrose Dec 15, 2025
f30cd84
another flaky test fix - common theme here is that raising an error k…
kevin-montrose Dec 15, 2025
a0042e5
these tests are super chatty, suppress logging for PR CI purposes
kevin-montrose Dec 15, 2025
9f956e7
address feedback; sizeof(byte) is unnecessary as namespace is part of…
kevin-montrose Dec 15, 2025
e1aa007
grow and shrink records during vector set delete tracking
kevin-montrose Dec 15, 2025
fef574c
fix WRONGTYPE for Vector Set ops on non-Vector Set keys - still cance…
kevin-montrose Dec 16, 2025
d453de6
Implement VINFO (#1469)
tiagonapoli Dec 17, 2025
3669587
dotnet format
Dec 18, 2025
f1dfa19
typo
kevin-montrose Dec 18, 2025
c708435
Merge branch 'vectorApiPoC' of https://github.com/microsoft/garnet in…
kevin-montrose Dec 18, 2025
be98542
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 6, 2026
c5987da
validate that values will fit in store before calling into DiskANN
kevin-montrose Jan 6, 2026
c0f67bd
validate minimum page size (16k for now, 8k is actual internal minimu…
kevin-montrose Jan 6, 2026
32fc013
disable low memory in DiskANNServiceTests
kevin-montrose Jan 7, 2026
509b5bb
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 8, 2026
ab168dd
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 12, 2026
590cc17
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 14, 2026
a3e2a49
bump up to 1.0.17
kevin-montrose Jan 15, 2026
748e1ba
update tests for variable length
kevin-montrose Jan 15, 2026
305f6c1
fix VEMB, fix tests; all non-cluster tests passing
kevin-montrose Jan 16, 2026
6df6481
bump to 1.0.18
kevin-montrose Jan 20, 2026
2dee337
repro cluster regression in non-cluster context; VREM is leaving data…
kevin-montrose Jan 20, 2026
42e69e4
add (failing) tests and calls for check_internal_id_valid(...) agains…
kevin-montrose Jan 20, 2026
5e57de4
bump to 1.0.19 which implements check_internal_id_valid; there are st…
kevin-montrose Jan 21, 2026
f73fa6b
undo prefix managling on DiskANN provided buffers
kevin-montrose Jan 21, 2026
259513f
Update diskann-garnet and add distance metric to VINFO (#1505)
tiagonapoli Jan 22, 2026
84aa8a0
wire distance metric up throughout
kevin-montrose Jan 22, 2026
354cb8d
fixes around distance metric addition
kevin-montrose Jan 22, 2026
13ad372
Implement VGETATTR (#1474)
tiagonapoli Jan 23, 2026
6c1ef0d
minor cleanup as part of syncing into dev targetting branch
kevin-montrose Jan 23, 2026
c7a31c0
merge main; move vector set replication tasks over to TaskManager
kevin-montrose Jan 23, 2026
0247985
Create Grid tests for DiskANN (#1513)
tiagonapoli Jan 26, 2026
c60189c
dotnet format
Jan 26, 2026
8f5c03c
bump to 1.0.20
kevin-montrose Jan 28, 2026
d1361e5
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 28, 2026
197a8ce
slap Allure attributes everywhere new
kevin-montrose Jan 28, 2026
7d720a8
Merge branch 'main' into vectorApiPoC
kevin-montrose Jan 28, 2026
461a0de
missed an allure attribute
kevin-montrose Jan 28, 2026
7138778
missed an allure inherit
kevin-montrose Jan 28, 2026
cf40005
missed more allure inherits
kevin-montrose Jan 28, 2026
349df54
Fix VGETATTR and VSIM for large attributes
Jan 29, 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
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
<PackageVersion Include="System.Numerics.Tensors" Version="9.0.9" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.8" />
<PackageVersion Include="diskann-garnet" Version="1.0.20" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public sealed unsafe partial class GarnetClientSession : IServerHook, IMessageCo

static ReadOnlySpan<byte> MAIN_STORE => "SSTORE"u8;
static ReadOnlySpan<byte> OBJECT_STORE => "OSTORE"u8;
static ReadOnlySpan<byte> VECTOR_STORE => "VSTORE"u8;
static ReadOnlySpan<byte> T => "T"u8;
static ReadOnlySpan<byte> F => "F"u8;

Expand Down Expand Up @@ -170,14 +171,30 @@ public Task<string> SetSlotRange(Memory<byte> state, string nodeid, List<(int, i
/// <param name="sourceNodeId"></param>
/// <param name="replace"></param>
/// <param name="isMainStore"></param>
public void SetClusterMigrateHeader(string sourceNodeId, bool replace, bool isMainStore)
public void SetClusterMigrateHeader(string sourceNodeId, bool replace, bool isMainStore, bool isVectorSets)
{
currTcsIterationTask = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
tcsQueue.Enqueue(currTcsIterationTask);
curr = offset;
this.isMainStore = isMainStore;
this.ist = IncrementalSendType.MIGRATE;
var storeType = isMainStore ? MAIN_STORE : OBJECT_STORE;
ReadOnlySpan<byte> storeType;
if (isMainStore)
{
if (isVectorSets)
{
storeType = VECTOR_STORE;
}
else
{
storeType = MAIN_STORE;
}
}
else
{
storeType = OBJECT_STORE;
}

var replaceOption = replace ? T : F;

var arraySize = 6;
Expand Down Expand Up @@ -249,7 +266,7 @@ public void SetClusterMigrateHeader(string sourceNodeId, bool replace, bool isMa
/// <returns></returns>
public Task<string> CompleteMigrate(string sourceNodeId, bool replace, bool isMainStore)
{
SetClusterMigrateHeader(sourceNodeId, replace, isMainStore);
SetClusterMigrateHeader(sourceNodeId, replace, isMainStore, isVectorSets: false);

Debug.Assert(end - curr >= 2);
*curr++ = (byte)'\r';
Expand Down
25 changes: 15 additions & 10 deletions libs/cluster/Server/ClusterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,22 +240,27 @@ public string GetInfo()
public static string GetRange(int[] slots)
{
var range = "> ";
var start = slots[0];
var end = slots[0];
for (var i = 1; i < slots.Length + 1; i++)
if (slots.Length >= 1)
{
if (i < slots.Length && slots[i] == end + 1)
end = slots[i];
else

var start = slots[0];
var end = slots[0];
for (var i = 1; i < slots.Length + 1; i++)
{
range += $"{start}-{end} ";
if (i < slots.Length)
{
start = slots[i];
if (i < slots.Length && slots[i] == end + 1)
end = slots[i];
else
{
range += $"{start}-{end} ";
if (i < slots.Length)
{
start = slots[i];
end = slots[i];
}
}
}
}

return range;
}

Expand Down
5 changes: 4 additions & 1 deletion libs/cluster/Server/ClusterManagerSlotState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ namespace Garnet.cluster
SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>,
BasicContext<byte[], IGarnetObject, ObjectInput, GarnetObjectStoreOutput, long, ObjectSessionFunctions,
/* ObjectStoreFunctions */ StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>,
GenericAllocator<byte[], IGarnetObject, StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>>>>;
GenericAllocator<byte[], IGarnetObject, StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>>>,
BasicContext<SpanByte, SpanByte, VectorInput, SpanByte, long, VectorSessionFunctions,
/* VectorStoreFunctions */ StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>,
SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>>;

/// <summary>
/// Cluster manager
Expand Down
4 changes: 4 additions & 0 deletions libs/cluster/Server/ClusterManagerWorkerState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ public bool TryAddReplica(string nodeid, bool force, bool upgradeLock, out ReadO
clusterProvider.replicationManager.EndRecovery(RecoveryStatus.NoRecovery, downgradeLock: false);
}
}

clusterProvider.storeWrapper.SuspendPrimaryOnlyTasks().Wait();
clusterProvider.storeWrapper.StartReplicaTasks();

FlushConfig();
return true;
}
Expand Down
15 changes: 12 additions & 3 deletions libs/cluster/Server/ClusterProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@

namespace Garnet.cluster
{
using BasicContext = BasicContext<SpanByte, SpanByte, RawStringInput, SpanByteAndMemory, long, MainSessionFunctions,
/* MainStoreFunctions */ StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>,
SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>;

using BasicGarnetApi = GarnetApi<BasicContext<SpanByte, SpanByte, RawStringInput, SpanByteAndMemory, long, MainSessionFunctions,
/* MainStoreFunctions */ StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>,
SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>,
BasicContext<byte[], IGarnetObject, ObjectInput, GarnetObjectStoreOutput, long, ObjectSessionFunctions,
/* ObjectStoreFunctions */ StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>,
GenericAllocator<byte[], IGarnetObject, StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>>>>;
GenericAllocator<byte[], IGarnetObject, StoreFunctions<byte[], IGarnetObject, ByteArrayKeyComparer, DefaultRecordDisposer<byte[], IGarnetObject>>>>,
BasicContext<SpanByte, SpanByte, VectorInput, SpanByte, long, VectorSessionFunctions,
/* VectorStoreFunctions */ StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>,
SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>>;

using VectorContext = BasicContext<SpanByte, SpanByte, VectorInput, SpanByte, long, VectorSessionFunctions, StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>, SpanByteAllocator<StoreFunctions<SpanByte, SpanByte, SpanByteComparer, SpanByteRecordDisposer>>>;

/// <summary>
/// Cluster provider
Expand Down Expand Up @@ -100,8 +109,8 @@ public void Start()
}

/// <inheritdoc />
public IClusterSession CreateClusterSession(TransactionManager txnManager, IGarnetAuthenticator authenticator, UserHandle userHandle, GarnetSessionMetrics garnetSessionMetrics, BasicGarnetApi basicGarnetApi, INetworkSender networkSender, ILogger logger = null)
=> new ClusterSession(this, txnManager, authenticator, userHandle, garnetSessionMetrics, basicGarnetApi, networkSender, logger);
public IClusterSession CreateClusterSession(TransactionManager txnManager, IGarnetAuthenticator authenticator, UserHandle userHandle, GarnetSessionMetrics garnetSessionMetrics, BasicGarnetApi basicGarnetApi, BasicContext basicContext, VectorContext vectorContext, INetworkSender networkSender, ILogger logger = null)
=> new ClusterSession(this, txnManager, authenticator, userHandle, garnetSessionMetrics, basicGarnetApi, basicContext, vectorContext, networkSender, logger);

/// <inheritdoc />
public void UpdateClusterAuth(string clusterUsername, string clusterPassword)
Expand Down
3 changes: 3 additions & 0 deletions libs/cluster/Server/Failover/ReplicaFailoverSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ public async Task<bool> BeginAsyncReplicaFailover()
// Attach to old replicas, and old primary if DEFAULT option
await IssueAttachReplicas();

await clusterProvider.storeWrapper.SuspendReplicaOnlyTasks();
clusterProvider.storeWrapper.StartPrimaryTasks();

return true;
}
catch (Exception ex)
Expand Down
112 changes: 106 additions & 6 deletions libs/cluster/Server/Migration/MigrateOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// Licensed under the MIT license.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Garnet.client;
using Garnet.server;
using Microsoft.Extensions.Logging;
using Tsavorite.core;

namespace Garnet.cluster
Expand All @@ -18,16 +20,25 @@ internal sealed partial class MigrateOperation
public MainStoreScan mss;
public ObjectStoreScan oss;

private readonly ConcurrentDictionary<byte[], byte[]> vectorSetsIndexKeysToMigrate;

readonly MigrateSession session;
readonly GarnetClientSession gcs;
readonly LocalServerSession localServerSession;

public GarnetClientSession Client => gcs;

public IEnumerable<KeyValuePair<byte[], byte[]>> VectorSets => vectorSetsIndexKeysToMigrate;

public void ThrowIfCancelled() => session._cts.Token.ThrowIfCancellationRequested();

public bool Contains(int slot) => session._sslots.Contains(slot);

public bool ContainsNamespace(ulong ns) => session._namespaces?.Contains(ns) ?? false;

public void EncounteredVectorSet(byte[] key, byte[] value)
=> vectorSetsIndexKeysToMigrate.TryAdd(key, value);

public MigrateOperation(MigrateSession session, Sketch sketch = null, int batchSize = 1 << 18)
{
this.session = session;
Expand All @@ -37,6 +48,7 @@ public MigrateOperation(MigrateSession session, Sketch sketch = null, int batchS
mss = new MainStoreScan(this);
oss = new ObjectStoreScan(this);
keysToDelete = [];
vectorSetsIndexKeysToMigrate = new(ByteArrayComparer.Instance);
}

public bool Initialize()
Expand Down Expand Up @@ -72,7 +84,7 @@ public void Scan(StoreType storeType, ref long currentAddress, long endAddress)
/// </summary>
/// <param name="storeType"></param>
/// <returns></returns>
public bool TrasmitSlots(StoreType storeType)
public bool TransmitSlots(StoreType storeType)
{
var bufferSize = 1 << 10;
SectorAlignedMemory buffer = new(bufferSize, 1);
Expand All @@ -87,7 +99,7 @@ public bool TrasmitSlots(StoreType storeType)
{
foreach (var key in sketch.argSliceVector)
{
var spanByte = key.SpanByte;
var spanByte = key;
if (!session.WriteOrSendMainStoreKeyValuePair(gcs, localServerSession, ref spanByte, ref input, ref o, out _))
return false;

Expand Down Expand Up @@ -117,7 +129,10 @@ public bool TrasmitSlots(StoreType storeType)
return true;
}

public bool TransmitKeys(StoreType storeType)
/// <summary>
/// Move keys in sketch out of the given store, UNLESS they are also in <paramref name="vectorSetKeysToIgnore"/>.
/// </summary>
public bool TransmitKeys(StoreType storeType, Dictionary<byte[], byte[]> vectorSetKeysToIgnore)
{
var bufferSize = 1 << 10;
SectorAlignedMemory buffer = new(bufferSize, 1);
Expand All @@ -131,12 +146,30 @@ public bool TransmitKeys(StoreType storeType)
var keys = sketch.Keys;
if (storeType == StoreType.Main)
{
#if NET9_0_OR_GREATER
var ignoreLookup = vectorSetKeysToIgnore.GetAlternateLookup<ReadOnlySpan<byte>>();
#endif

for (var i = 0; i < keys.Count; i++)
{
if (keys[i].Item2)
continue;

var spanByte = keys[i].Item1.SpanByte;

// Don't transmit if a Vector Set
var isVectorSet =
vectorSetKeysToIgnore.Count > 0 &&
#if NET9_0_OR_GREATER
ignoreLookup.ContainsKey(spanByte.AsReadOnlySpan());
#else
vectorSetKeysToIgnore.ContainsKey(spanByte.ToByteArray());
#endif
if (isVectorSet)
{
continue;
}

if (!session.WriteOrSendMainStoreKeyValuePair(gcs, localServerSession, ref spanByte, ref input, ref o, out var status))
return false;

Expand All @@ -158,8 +191,8 @@ public bool TransmitKeys(StoreType storeType)
if (keys[i].Item2)
continue;

var argSlice = keys[i].Item1;
if (!session.WriteOrSendObjectStoreKeyValuePair(gcs, localServerSession, ref argSlice, out var status))
var spanByte = keys[i].Item1.SpanByte;
if (!session.WriteOrSendObjectStoreKeyValuePair(gcs, localServerSession, ref spanByte, out var status))
return false;

// Skip if key NOTFOUND
Expand All @@ -182,6 +215,54 @@ public bool TransmitKeys(StoreType storeType)
return true;
}

/// <summary>
/// Transmit data in namespaces during a MIGRATE ... KEYS operation.
///
/// Doesn't delete anything, just scans and transmits.
/// </summary>
public bool TransmitKeysNamespaces(ILogger logger)
{
var migrateOperation = this;

if (!migrateOperation.Initialize())
return false;

var workerStartAddress = migrateOperation.session.clusterProvider.storeWrapper.store.Log.BeginAddress;
var workerEndAddress = migrateOperation.session.clusterProvider.storeWrapper.store.Log.TailAddress;

var cursor = workerStartAddress;
logger?.LogWarning("<MainStore> migrate keys (namespaces) scan range [{workerStartAddress}, {workerEndAddress}]", workerStartAddress, workerEndAddress);
while (true)
{
var current = cursor;
// Build Sketch
migrateOperation.sketch.SetStatus(SketchStatus.INITIALIZING);
migrateOperation.Scan(StoreType.Main, ref current, workerEndAddress);

// Stop if no keys have been found
if (migrateOperation.sketch.argSliceVector.IsEmpty) break;

logger?.LogWarning("Scan from {cursor} to {current} and discovered {count} keys", cursor, current, migrateOperation.sketch.argSliceVector.Count);

// Transition EPSM to MIGRATING
migrateOperation.sketch.SetStatus(SketchStatus.TRANSMITTING);
migrateOperation.session.WaitForConfigPropagation();

// Transmit all keys gathered
migrateOperation.TransmitSlots(StoreType.Main);

// Transition EPSM to DELETING
migrateOperation.sketch.SetStatus(SketchStatus.DELETING);
migrateOperation.session.WaitForConfigPropagation();

// Clear keys from buffer
migrateOperation.sketch.Clear();
cursor = current;
}

return true;
}

/// <summary>
/// Delete keys after migration if copyOption is not set
/// </summary>
Expand All @@ -193,7 +274,13 @@ public void DeleteKeys()
{
foreach (var key in sketch.argSliceVector)
{
var spanByte = key.SpanByte;
if (key.MetadataSize == 1)
{
// Namespace'd keys are not deleted here, but when migration finishes
continue;
}

var spanByte = key;
_ = localServerSession.BasicGarnetApi.DELETE(ref spanByte);
}
}
Expand All @@ -209,6 +296,19 @@ public void DeleteKeys()
}
}
}

/// <summary>
/// Delete a Vector Set after migration if _copyOption is not set.
/// </summary>
public void DeleteVectorSet(ref SpanByte key)
{
if (session._copyOption)
return;

var delRes = localServerSession.BasicGarnetApi.DELETE(ref key);

session.logger?.LogDebug("Deleting Vector Set {key} after migration: {delRes}", System.Text.Encoding.UTF8.GetString(key.AsReadOnlySpan()), delRes);
}
}
}
}
Loading