From 6a2b178d2125dcf79750e12d45f0fa71da8c4284 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sun, 8 Sep 2024 00:27:22 +0200 Subject: [PATCH] Set NextOpIndex after loading BTree to remove skipped regions on op index. --- src/ZoneTree.UnitTests/OpIndexTests.cs | 68 +++++++++++++++++-- src/ZoneTree/Directory.Build.props | 4 +- .../Segments/InMemory/MutableSegment.cs | 3 +- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/ZoneTree.UnitTests/OpIndexTests.cs b/src/ZoneTree.UnitTests/OpIndexTests.cs index 4360abd..e941e7b 100644 --- a/src/ZoneTree.UnitTests/OpIndexTests.cs +++ b/src/ZoneTree.UnitTests/OpIndexTests.cs @@ -31,19 +31,77 @@ void CreateData() maintainer.WaitForBackgroundThreads(); } - void ReloadData() + void ReloadData(int expectedIndex, bool drop = false) { using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetMutableSegmentMaxItemCount(100) .Open(); - var opIndex = zoneTree.Upsert(recordCount + 1, recordCount + 1); - Assert.That(opIndex, Is.EqualTo(recordCount + 1)); - zoneTree.Maintenance.Drop(); + var opIndex = zoneTree.Upsert(expectedIndex, expectedIndex); + Assert.That(opIndex, Is.EqualTo(expectedIndex)); + if (drop) + zoneTree.Maintenance.Drop(); } + CreateData(); - ReloadData(); + ReloadData(recordCount + 1); + ReloadData(recordCount + 2); + ReloadData(recordCount + 3, true); + + Assert.IsTrue( + opIndexes.Order().ToArray() + .SequenceEqual(Enumerable.Range(1, recordCount).Select(x => (long)x))); + } + + [Test] + public void TestOpIndex2() + { + var dataPath = "data/TestOpIndex2"; + if (Directory.Exists(dataPath)) + Directory.Delete(dataPath, true); + var recordCount = 10_000; + var opIndexes = new ConcurrentBag(); + void CreateData() + { + using var zoneTree = new ZoneTreeFactory() + .SetDataDirectory(dataPath) + .SetMutableSegmentMaxItemCount(100) + .OpenOrCreate(); + + using var maintainer = zoneTree.CreateMaintainer(); + Parallel.For(0, recordCount, (i) => + { + var opIndex = zoneTree.Upsert(i, i); + opIndexes.Add(opIndex); + }); + maintainer.EvictToDisk(); + maintainer.WaitForBackgroundThreads(); + } + + void ReloadData(int expectedIndex, bool drop = false) + { + using var zoneTree = new ZoneTreeFactory() + .SetDataDirectory(dataPath) + .SetMutableSegmentMaxItemCount(100) + .Open(); + + var opIndex = zoneTree.Upsert(expectedIndex, expectedIndex); + Assert.That(opIndex, Is.EqualTo(expectedIndex)); + + using var maintainer = zoneTree.CreateMaintainer(); + maintainer.EvictToDisk(); + maintainer.WaitForBackgroundThreads(); + + if (drop) + zoneTree.Maintenance.Drop(); + } + + CreateData(); + ReloadData(recordCount + 1); + ReloadData(recordCount + 2); + ReloadData(recordCount + 3, true); + Assert.IsTrue( opIndexes.Order().ToArray() .SequenceEqual(Enumerable.Range(1, recordCount).Select(x => (long)x))); diff --git a/src/ZoneTree/Directory.Build.props b/src/ZoneTree/Directory.Build.props index 5b024ff..4017992 100644 --- a/src/ZoneTree/Directory.Build.props +++ b/src/ZoneTree/Directory.Build.props @@ -5,8 +5,8 @@ Ahmed Yasin Koculu ZoneTree ZoneTree - 1.8.1.0 - 1.8.1.0 + 1.8.2.0 + 1.8.2.0 Ahmed Yasin Koculu ZoneTree ZoneTree is a persistent, high-performance, transactional, ACID-compliant ordered key-value database for NET. It can operate in memory or on local/cloud storage. diff --git a/src/ZoneTree/Segments/InMemory/MutableSegment.cs b/src/ZoneTree/Segments/InMemory/MutableSegment.cs index 748a650..87b82a7 100644 --- a/src/ZoneTree/Segments/InMemory/MutableSegment.cs +++ b/src/ZoneTree/Segments/InMemory/MutableSegment.cs @@ -82,7 +82,6 @@ public MutableSegment( null, Options.BTreeNodeSize, Options.BTreeLeafSize); - BTree.SetNextOpIndex(nextOpIndex); MarkValueDeleted = options.MarkValueDeleted; MutableSegmentMaxItemCount = options.MutableSegmentMaxItemCount; @@ -96,6 +95,8 @@ public MutableSegment( { LoadLogEntries(keys, values); } + // set op index after loading entries. + BTree.SetNextOpIndex(nextOpIndex); } void LoadLogEntries(IReadOnlyList keys, IReadOnlyList values)