Skip to content

Commit 84221bb

Browse files
hkhalidCopilot
authored andcommitted
Migrate LiteLsm reads to iterator API, remove class-based SkipList
- Remove SkipList.cs (class-based) and SkipListType enum; only StructSkipList remains - Make GetIterator public with ReadAll() yielding IEnumerable<(TKey, TValue)> - Fix LiteLsmIterator: buffer span bug, batch continuation via excludeStart - Fix ReadBatchInto to handle segment-to-memtable boundary transitions - Add excludeStart support through MemCpyRawRange and SegmentManager (O(log N) + O(1)) - Fix GetKeyIdxInDataLayer to return successor index for not-found keys - Fix SegmentManager FileShare for concurrent read/write access - Update tests and benchmarks to use iterator API - Add WaitForPendingFlush to write benchmark for fair comparison - Add concurrent stress test (50K inserts with parallel point + range readers) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent b106363 commit 84221bb

12 files changed

Lines changed: 1513 additions & 1422 deletions

File tree

benchmarks/StreamDB.Benchmarks/ReadBenchmarks.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,10 @@ public int LiteLsm_RangeRead()
290290
// LiteLsm has no secondary indexes — query ~1000 entries to match other single-index reads
291291
long startPi = BasePi + 10_000;
292292
long endPi = startPi + 1000;
293-
var results = _liteLsm.QueryRange(startPi, endPi).ToList();
294-
return results.Count;
293+
using var iter = _liteLsm.GetIterator(startPi, endPi);
294+
int count = 0;
295+
foreach (var _ in iter.ReadAll()) count++;
296+
return count;
295297
}
296298

297299
[Benchmark]
@@ -300,8 +302,10 @@ public int LiteLsm_MultiKeyRead()
300302
// Comparable to multi-index reads: query ~4000 entries
301303
long startPi = BasePi + 10_000;
302304
long endPi = startPi + 4000;
303-
var results = _liteLsm.QueryRange(startPi, endPi).ToList();
304-
return results.Count;
305+
using var iter = _liteLsm.GetIterator(startPi, endPi);
306+
int count = 0;
307+
foreach (var _ in iter.ReadAll()) count++;
308+
return count;
305309
}
306310

307311
[Benchmark]
@@ -310,16 +314,20 @@ public int LiteLsm_InMemory_RangeRead()
310314
// All data in memtable — no disk I/O
311315
long startPi = BasePi + 10_000;
312316
long endPi = startPi + 1000;
313-
var results = _liteLsmInMemory.QueryRange(startPi, endPi).ToList();
314-
return results.Count;
317+
using var iter = _liteLsmInMemory.GetIterator(startPi, endPi);
318+
int count = 0;
319+
foreach (var _ in iter.ReadAll()) count++;
320+
return count;
315321
}
316322

317323
[Benchmark]
318324
public int LiteLsm_InMemory_MultiKeyRead()
319325
{
320326
long startPi = BasePi + 10_000;
321327
long endPi = startPi + 4000;
322-
var results = _liteLsmInMemory.QueryRange(startPi, endPi).ToList();
323-
return results.Count;
328+
using var iter = _liteLsmInMemory.GetIterator(startPi, endPi);
329+
int count = 0;
330+
foreach (var _ in iter.ReadAll()) count++;
331+
return count;
324332
}
325333
}

benchmarks/StreamDB.Benchmarks/WriteBenchmarks.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ public void LiteLsm_SequentialWrites()
183183
{
184184
_liteLsm.Put(1_000_000 + i, payload);
185185
}
186+
_liteLsm.WaitForPendingFlush();
186187
}
187188

188189
private static void TryDelete(string? path)

src/StreamDB/BorrowedMemory.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace StreamDB
6+
{
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace StreamDB.LiteLsm;
2+
3+
public interface IMonotonicSkipList<TKey, TValue> where TKey : unmanaged, IComparable<TKey> where TValue : unmanaged
4+
{
5+
int Count { get; }
6+
//bool TryGetMinKey(out TKey key);
7+
//bool TryGetMaxKey(out TKey key);
8+
bool ProbablyContainsKey(TKey key);
9+
void Clear();
10+
IEnumerable<KeyValuePair<TKey, TValue>> GetAll();
11+
ReadOnlySpan<byte> GetRawDataLayer();
12+
void InsertMonotonic(TKey key, TValue value);
13+
bool TryGetValue(TKey key, out TValue value);
14+
(bool, int) MemCpyRawRange(TKey fromKey, TKey endKey, Span<(TKey, TValue)> buffer, bool excludeStart = false);
15+
}

src/StreamDB/LiteLsm/IStructSkipList.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)