From 8aaac2e7337e0e305396c05225d8cb3b78539213 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sat, 7 Sep 2024 00:19:16 +0200 Subject: [PATCH 1/3] Add key argument into isDeleted delegate. --- README.md | 8 +-- src/ZoneTree.UnitTests/CountTests.cs | 2 +- .../FixedSizeKeyAndValueTests.cs | 4 +- src/ZoneTree.UnitTests/IteratorTests.cs | 12 ++-- .../MergeEmptySegmentsTest.cs | 12 ++-- .../OptimisticTransactionTests.cs | 16 ++--- src/ZoneTree.UnitTests/TTLTests.cs | 8 +-- src/ZoneTree/Collections/DictionaryWithWal.cs | 4 +- .../Core/ZoneTree.BottomSegments.Merge.cs | 2 +- src/ZoneTree/Core/ZoneTree.Merge.cs | 2 +- src/ZoneTree/Core/ZoneTree.ReadWrite.cs | 14 ++-- src/ZoneTree/Core/ZoneTree.cs | 7 +- src/ZoneTree/Core/ZoneTreeIterator.cs | 6 +- src/ZoneTree/Directory.Build.props | 4 +- src/ZoneTree/Options/ZoneTreeOptions.cs | 16 +++-- .../PresetTypes/ComponentsForKnownTypes.cs | 65 ++++++++++--------- .../Segments/InMemory/MutableSegment.cs | 2 +- .../Transactional/BasicTransactionLog.cs | 4 +- .../Transactional/OptimisticZoneTree.cs | 4 +- src/ZoneTree/WAL/WriteAheadLogUtility.cs | 4 +- src/ZoneTree/ZoneTreeFactory.cs | 6 +- src/ZoneTree/docs/ZoneTree/README-NUGET.md | 6 +- 22 files changed, 106 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 6f1719b..a24e743 100644 --- a/README.md +++ b/README.md @@ -227,8 +227,8 @@ In this example, `-1` is used as the deletion marker for integer values: using Tenray.ZoneTree; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); // Deleting a key by setting its value to -1 @@ -251,8 +251,8 @@ struct MyDeletableValueType } using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in MyDeletableValueType x) => x.IsDeleted) - .SetMarkValueDeletedDelegate((ref MyDeletableValueType x) => x.IsDeleted = true) + .SetIsValueDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) + .SetMarkValueDeletedDelegate((ref MyDeletableValueType value) => value.IsDeleted = true) .OpenOrCreate(); // Deleting a key by setting the IsDeleted flag diff --git a/src/ZoneTree.UnitTests/CountTests.cs b/src/ZoneTree.UnitTests/CountTests.cs index c44dcb2..cbc2f4f 100644 --- a/src/ZoneTree.UnitTests/CountTests.cs +++ b/src/ZoneTree.UnitTests/CountTests.cs @@ -19,7 +19,7 @@ public void CountRecordsDuringAMerge( Directory.Delete(dataPath, true); using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => x == -1) + .SetIsValueDeletedDelegate((in string key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int x) => x = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) diff --git a/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs b/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs index 4c54a06..6d18b59 100644 --- a/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs +++ b/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs @@ -312,8 +312,8 @@ static void ReloadIntIntTreeTestHelper(string dataPath, bool destroy) .SetWriteAheadLogDirectory(dataPath) .ConfigureWriteAheadLogOptions(x => x.WriteAheadLogMode = WriteAheadLogMode.Sync) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var n = 2000; var deleted = new HashSet() { 11, 99, 273, 200, 333, 441, 203, 499, 666 }; diff --git a/src/ZoneTree.UnitTests/IteratorTests.cs b/src/ZoneTree.UnitTests/IteratorTests.cs index b741f29..ba70de7 100644 --- a/src/ZoneTree.UnitTests/IteratorTests.cs +++ b/src/ZoneTree.UnitTests/IteratorTests.cs @@ -19,8 +19,8 @@ public void IntIntIterator() .SetMutableSegmentMaxItemCount(11) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 250; var b = 500; @@ -89,8 +89,8 @@ public void IntIntIteratorSeek() .SetMutableSegmentMaxItemCount(11) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 250; var b = 500; @@ -180,8 +180,8 @@ public void IntIntIteratorReflectNewInserts() .SetMutableSegmentMaxItemCount(250) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 251; var b = 500; diff --git a/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs b/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs index 6c539d8..31b7339 100644 --- a/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs +++ b/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs @@ -16,8 +16,8 @@ public void MergeEmptySegments( Directory.Delete(dataPath, true); using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => true) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => true) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) @@ -64,8 +64,8 @@ public void MergeDeletedSegments( var isRecordDeleted = false; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => isRecordDeleted) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => isRecordDeleted) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) @@ -124,8 +124,8 @@ public void MergeDeletedBottomSegments( var isRecordDeleted = false; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => isRecordDeleted) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => isRecordDeleted) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDiskSegmentMaxItemCount(250) .SetDataDirectory(dataPath) diff --git a/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs b/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs index 0828c03..dc6f54f 100644 --- a/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs +++ b/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs @@ -119,8 +119,8 @@ public void ReadCommittedTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold; @@ -172,8 +172,8 @@ public void TransactionLogCompactionTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold; @@ -219,8 +219,8 @@ public void TransactionLogCompactionWithSkipWriteRule(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold; @@ -254,8 +254,8 @@ public void TransactionIsolationTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold; diff --git a/src/ZoneTree.UnitTests/TTLTests.cs b/src/ZoneTree.UnitTests/TTLTests.cs index 4627092..5d61454 100644 --- a/src/ZoneTree.UnitTests/TTLTests.cs +++ b/src/ZoneTree.UnitTests/TTLTests.cs @@ -17,8 +17,8 @@ public void TestTTL() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) .SetValueSerializer(new StructSerializer>()) - .SetIsValueDeletedDelegate((in TTLValue x) => x.IsExpired) - .SetMarkValueDeletedDelegate(void (ref TTLValue x) => x.Expire()) + .SetIsValueDeletedDelegate((in int key, in TTLValue value) => value.IsExpired) + .SetMarkValueDeletedDelegate(void (ref TTLValue value) => value.Expire()) .OpenOrCreate(); zoneTree.Upsert(5, new TTLValue(99, DateTime.UtcNow.AddMilliseconds(300))); @@ -33,8 +33,8 @@ public void TestTTL() Thread.Sleep(150); f1 = zoneTree.TryGetAndUpdate( 5, - out v1, - bool (ref TTLValue v) => + out v1, + bool (ref TTLValue v) => v.SlideExpiration(TimeSpan.FromMilliseconds(300))); Thread.Sleep(450); // initial expiration (300) + slided expiration (300) - Thread.Sleep(150) f2 = zoneTree.TryGetAndUpdate( diff --git a/src/ZoneTree/Collections/DictionaryWithWal.cs b/src/ZoneTree/Collections/DictionaryWithWal.cs index d486676..f48618c 100644 --- a/src/ZoneTree/Collections/DictionaryWithWal.cs +++ b/src/ZoneTree/Collections/DictionaryWithWal.cs @@ -28,7 +28,7 @@ public sealed class DictionaryWithWAL : IDisposable readonly IRefComparer Comparer; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsValueDeletedDelegate IsValueDeleted; readonly MarkValueDeletedDelegate MarkValueDeleted; @@ -54,7 +54,7 @@ public DictionaryWithWAL( ISerializer keySerializer, ISerializer valueSerializer, IRefComparer comparer, - IsValueDeletedDelegate isValueDeleted, + IsValueDeletedDelegate isValueDeleted, MarkValueDeletedDelegate markValueDeleted) { WriteAheadLogProvider = writeAheadLogProvider; diff --git a/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs b/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs index d8700cd..4d7c1c1 100644 --- a/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs +++ b/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs @@ -184,7 +184,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries if writeDeletedValues is false. - if (!writeDeletedValues && IsValueDeleted(minEntry.Value)) + if (!writeDeletedValues && IsValueDeleted(minEntry.Key, minEntry.Value)) { skipElement(); prevKey = minEntry.Key; diff --git a/src/ZoneTree/Core/ZoneTree.Merge.cs b/src/ZoneTree/Core/ZoneTree.Merge.cs index 7842178..5607144 100644 --- a/src/ZoneTree/Core/ZoneTree.Merge.cs +++ b/src/ZoneTree/Core/ZoneTree.Merge.cs @@ -230,7 +230,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries if bottom segments queue is empty. - if (!hasBottomSegments && IsValueDeleted(minEntry.Value)) + if (!hasBottomSegments && IsValueDeleted(minEntry.Key, minEntry.Value)) { skipElement(); prevKey = minEntry.Key; diff --git a/src/ZoneTree/Core/ZoneTree.ReadWrite.cs b/src/ZoneTree/Core/ZoneTree.ReadWrite.cs index a4ccde0..f9e0cd5 100644 --- a/src/ZoneTree/Core/ZoneTree.ReadWrite.cs +++ b/src/ZoneTree/Core/ZoneTree.ReadWrite.cs @@ -11,7 +11,7 @@ public bool ContainsKey(in TKey key) if (MutableSegment.ContainsKey(key)) { if (MutableSegment.TryGet(key, out TValue value)) - return !IsValueDeleted(value); + return !IsValueDeleted(key, value); } return TryGetFromReadonlySegments(in key, out _); @@ -23,7 +23,7 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value) { if (segment.TryGet(key, out value)) { - return !IsValueDeleted(value); + return !IsValueDeleted(key, value); } } @@ -33,14 +33,14 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value) { if (DiskSegment.TryGet(key, out value)) { - return !IsValueDeleted(value); + return !IsValueDeleted(key, value); } foreach (var segment in BottomSegmentQueue) { if (segment.TryGet(key, out value)) { - return !IsValueDeleted(value); + return !IsValueDeleted(key, value); } } return false; @@ -56,7 +56,7 @@ public bool TryGet(in TKey key, out TValue value) { if (MutableSegment.TryGet(key, out value)) { - return !IsValueDeleted(value); + return !IsValueDeleted(key, value); } return TryGetFromReadonlySegments(in key, out value); } @@ -76,7 +76,7 @@ public bool TryGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDelegate< if (MutableSegment.TryGet(key, out value)) { - if (IsValueDeleted(value)) + if (IsValueDeleted(key, value)) return false; } else if (!TryGetFromReadonlySegments(in key, out value)) @@ -101,7 +101,7 @@ public bool TryAtomicGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDel { if (MutableSegment.TryGet(key, out value)) { - if (IsValueDeleted(value)) + if (IsValueDeleted(key, value)) return false; } else if (!TryGetFromReadonlySegments(in key, out value)) diff --git a/src/ZoneTree/Core/ZoneTree.cs b/src/ZoneTree/Core/ZoneTree.cs index 4e9512e..73d98a7 100644 --- a/src/ZoneTree/Core/ZoneTree.cs +++ b/src/ZoneTree/Core/ZoneTree.cs @@ -26,7 +26,7 @@ public sealed partial class ZoneTree : IZoneTree, IZ readonly MaxHeapEntryRefComparer MaxHeapEntryComparer; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsValueDeletedDelegate IsValueDeleted; readonly SingleProducerSingleConsumerQueue> ReadOnlySegmentQueue = new(); @@ -304,8 +304,9 @@ public long Count() var count = diskSegment.Length; while (iterator.Next()) { - var hasKey = diskSegment.ContainsKey(iterator.CurrentKey); - var isValueDeleted = IsValueDeleted(iterator.CurrentValue); + var key = iterator.CurrentKey; + var hasKey = diskSegment.ContainsKey(key); + var isValueDeleted = IsValueDeleted(key, iterator.CurrentValue); if (hasKey) { if (isValueDeleted) diff --git a/src/ZoneTree/Core/ZoneTreeIterator.cs b/src/ZoneTree/Core/ZoneTreeIterator.cs index cb49d24..945cb17 100644 --- a/src/ZoneTree/Core/ZoneTreeIterator.cs +++ b/src/ZoneTree/Core/ZoneTreeIterator.cs @@ -18,7 +18,7 @@ public sealed class ZoneTreeIterator : IZoneTreeIterator> SeekableIterators; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsValueDeletedDelegate IsValueDeleted; readonly IRefComparer Comparer; @@ -280,7 +280,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries. - if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Value)) + if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Key, minEntry.Value)) { skipElement(); PrevKey = minEntry.Key; @@ -330,7 +330,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries. - if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Value)) + if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Key, minEntry.Value)) { skipElement(); PrevKey = minEntry.Key; diff --git a/src/ZoneTree/Directory.Build.props b/src/ZoneTree/Directory.Build.props index 68a73ed..5b024ff 100644 --- a/src/ZoneTree/Directory.Build.props +++ b/src/ZoneTree/Directory.Build.props @@ -5,8 +5,8 @@ Ahmed Yasin Koculu ZoneTree ZoneTree - 1.8.0.0 - 1.8.0.0 + 1.8.1.0 + 1.8.1.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/Options/ZoneTreeOptions.cs b/src/ZoneTree/Options/ZoneTreeOptions.cs index d696afe..c93580f 100644 --- a/src/ZoneTree/Options/ZoneTreeOptions.cs +++ b/src/ZoneTree/Options/ZoneTreeOptions.cs @@ -10,12 +10,14 @@ namespace Tenray.ZoneTree.Options; /// -/// A delegate to query value deletion state. +/// A delegate to query key-value pair deletion state. /// /// The value type +/// The key type +/// Key to be queried /// Value to be queried -/// true if value is deleted, false otherwise -public delegate bool IsValueDeletedDelegate(in TValue value); +/// true if the key-value pair is deleted, false otherwise +public delegate bool IsValueDeletedDelegate(in TKey key, in TValue value); /// /// A delegate to mark a value deleted. @@ -62,9 +64,9 @@ public sealed class ZoneTreeOptions public ISerializer ValueSerializer { get; set; } /// - /// Delegate to query value deletion state. + /// Delegate to query key-value pair deletion state. /// - public IsValueDeletedDelegate IsValueDeleted { get; set; } + public IsValueDeletedDelegate IsValueDeleted { get; set; } /// /// Delegate to mark value deleted. @@ -223,7 +225,7 @@ public void Validate() public void CreateDefaultDeleteDelegates() { if (IsValueDeleted == null) - IsValueDeleted = ComponentsForKnownTypes.GetIsValueDeleted(); + IsValueDeleted = ComponentsForKnownTypes.GetIsValueDeleted(); if (MarkValueDeleted == null) MarkValueDeleted = ComponentsForKnownTypes.GetMarkValueDeleted(); } @@ -244,7 +246,7 @@ static bool IsAssignableToNull(Type type) /// public void DisableDeletion() { - IsValueDeleted = (in TValue _) => false; + IsValueDeleted = (in TKey _, in TValue _) => false; MarkValueDeleted = (ref TValue _) => { }; } } diff --git a/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs b/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs index 7d9ac29..3507d5b 100644 --- a/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs +++ b/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs @@ -94,53 +94,54 @@ public static ISerializer GetSerializer() } // Specific methods for checking if certain primitive types are considered deleted - static bool IsValueDeletedByte(in byte value) => value == default; - static bool IsValueDeletedChar(in char value) => value == default; - static bool IsValueDeletedDateTime(in DateTime value) => value == default; - static bool IsValueDeletedDecimal(in decimal value) => value == default; - static bool IsValueDeletedDouble(in double value) => value == default; - static bool IsValueDeletedShort(in short value) => value == default; - static bool IsValueDeletedUShort(in ushort value) => value == default; - static bool IsValueDeletedInt(in int value) => value == default; - static bool IsValueDeletedUInt(in uint value) => value == default; - static bool IsValueDeletedLong(in long value) => value == default; - static bool IsValueDeletedULong(in ulong value) => value == default; - static bool IsValueDeletedGuid(in Guid value) => value == default; - static bool IsValueDeletedMemoryByte(in Memory value) => value.Length == 0; - static bool IsValueDeletedReferenceType(in TValue value) => ReferenceEquals(value, default(TValue)); - static bool IsValueDeletedDefault(in TValue value) => EqualityComparer.Default.Equals(value, default); + static bool IsValueDeletedByte(in TKey key, in byte value) => value == default; + static bool IsValueDeletedChar(in TKey key, in char value) => value == default; + static bool IsValueDeletedDateTime(in TKey key, in DateTime value) => value == default; + static bool IsValueDeletedDecimal(in TKey key, in decimal value) => value == default; + static bool IsValueDeletedDouble(in TKey key, in double value) => value == default; + static bool IsValueDeletedShort(in TKey key, in short value) => value == default; + static bool IsValueDeletedUShort(in TKey key, in ushort value) => value == default; + static bool IsValueDeletedInt(in TKey key, in int value) => value == default; + static bool IsValueDeletedUInt(in TKey key, in uint value) => value == default; + static bool IsValueDeletedLong(in TKey key, in long value) => value == default; + static bool IsValueDeletedULong(in TKey key, in ulong value) => value == default; + static bool IsValueDeletedGuid(in TKey key, in Guid value) => value == default; + static bool IsValueDeletedMemoryByte(in TKey key, in Memory value) => value.Length == 0; + static bool IsValueDeletedReferenceType(in TKey key, in TValue value) => ReferenceEquals(value, default(TValue)); + static bool IsValueDeletedDefault(in TKey key, in TValue value) => EqualityComparer.Default.Equals(value, default); static void MarkValueDeletedDefault(ref TValue value) { value = default; } /// - /// Returns a delegate that checks if a value of a specific type is considered deleted. + /// Returns a delegate that checks if a key-value pair of a specific type is considered deleted. /// + /// The type of the key. /// The type of the value. /// A delegate that checks if the value is considered deleted. - public static IsValueDeletedDelegate GetIsValueDeleted() + public static IsValueDeletedDelegate GetIsValueDeleted() { - static IsValueDeletedDelegate Cast(object method) => - (IsValueDeletedDelegate)method; + static IsValueDeletedDelegate Cast(object method) => + (IsValueDeletedDelegate)method; TValue value = default; var result = value switch { - byte => Cast(new IsValueDeletedDelegate(IsValueDeletedByte)), - char => Cast(new IsValueDeletedDelegate(IsValueDeletedChar)), - DateTime => Cast(new IsValueDeletedDelegate(IsValueDeletedDateTime)), - decimal => Cast(new IsValueDeletedDelegate(IsValueDeletedDecimal)), - double => Cast(new IsValueDeletedDelegate(IsValueDeletedDouble)), - short => Cast(new IsValueDeletedDelegate(IsValueDeletedShort)), - ushort => Cast(new IsValueDeletedDelegate(IsValueDeletedUShort)), - int => Cast(new IsValueDeletedDelegate(IsValueDeletedInt)), - uint => Cast(new IsValueDeletedDelegate(IsValueDeletedUInt)), - long => Cast(new IsValueDeletedDelegate(IsValueDeletedLong)), - ulong => Cast(new IsValueDeletedDelegate(IsValueDeletedULong)), - Guid => Cast(new IsValueDeletedDelegate(IsValueDeletedGuid)), + byte => Cast(new IsValueDeletedDelegate(IsValueDeletedByte)), + char => Cast(new IsValueDeletedDelegate(IsValueDeletedChar)), + DateTime => Cast(new IsValueDeletedDelegate(IsValueDeletedDateTime)), + decimal => Cast(new IsValueDeletedDelegate(IsValueDeletedDecimal)), + double => Cast(new IsValueDeletedDelegate(IsValueDeletedDouble)), + short => Cast(new IsValueDeletedDelegate(IsValueDeletedShort)), + ushort => Cast(new IsValueDeletedDelegate(IsValueDeletedUShort)), + int => Cast(new IsValueDeletedDelegate(IsValueDeletedInt)), + uint => Cast(new IsValueDeletedDelegate(IsValueDeletedUInt)), + long => Cast(new IsValueDeletedDelegate(IsValueDeletedLong)), + ulong => Cast(new IsValueDeletedDelegate(IsValueDeletedULong)), + Guid => Cast(new IsValueDeletedDelegate(IsValueDeletedGuid)), _ => IsValueDeletedDefault }; if (typeof(TValue) == typeof(Memory)) - result = Cast(new IsValueDeletedDelegate>(IsValueDeletedMemoryByte)); + result = Cast(new IsValueDeletedDelegate>(IsValueDeletedMemoryByte)); if (RuntimeHelpers.IsReferenceOrContainsReferences()) return IsValueDeletedReferenceType; return result; diff --git a/src/ZoneTree/Segments/InMemory/MutableSegment.cs b/src/ZoneTree/Segments/InMemory/MutableSegment.cs index 47d03bf..359517d 100644 --- a/src/ZoneTree/Segments/InMemory/MutableSegment.cs +++ b/src/ZoneTree/Segments/InMemory/MutableSegment.cs @@ -126,7 +126,7 @@ void LoadLogEntriesWithGarbageCollection( continue; var value = values[i]; distinctKeys.Upsert(in key, 1, out _); - if (isValueDeleted(in value)) + if (isValueDeleted(in key, in value)) { continue; } diff --git a/src/ZoneTree/Transactional/BasicTransactionLog.cs b/src/ZoneTree/Transactional/BasicTransactionLog.cs index 31a6178..f16e013 100644 --- a/src/ZoneTree/Transactional/BasicTransactionLog.cs +++ b/src/ZoneTree/Transactional/BasicTransactionLog.cs @@ -65,11 +65,11 @@ public IReadOnlyList UncommittedTransactionIds } } - static bool IsTransactionMetaDeleted(in TransactionMeta value) => value.StartedAt == 0; + static bool IsTransactionMetaDeleted(in long key, in TransactionMeta value) => value.StartedAt == 0; static void MarkTransactionMetaDeleted(ref TransactionMeta value) { value.StartedAt = 0; } - static bool IsReadWriteStampDeleted(in ReadWriteStamp value) => value.IsDeleted; + static bool IsReadWriteStampDeleted(in TKey key, in ReadWriteStamp value) => value.IsDeleted; static void MarkReadWriteStampDeleted(ref ReadWriteStamp value) { value = default; } diff --git a/src/ZoneTree/Transactional/OptimisticZoneTree.cs b/src/ZoneTree/Transactional/OptimisticZoneTree.cs index f13a4ab..aead373 100644 --- a/src/ZoneTree/Transactional/OptimisticZoneTree.cs +++ b/src/ZoneTree/Transactional/OptimisticZoneTree.cs @@ -323,7 +323,7 @@ public bool ReadCommittedContainsKey(in TKey key, long currentTransactionId = -1 Debug.Assert(state != TransactionState.Aborted); - if (Options.IsValueDeleted(history.Value1)) + if (Options.IsValueDeleted(in key, history.Value1)) { return false; } @@ -374,7 +374,7 @@ public bool ReadCommittedTryGet(in TKey key, out TValue value, long currentTrans Debug.Assert(state != TransactionState.Aborted); - if (Options.IsValueDeleted(history.Value1)) + if (Options.IsValueDeleted(in key, history.Value1)) { value = default; return false; diff --git a/src/ZoneTree/WAL/WriteAheadLogUtility.cs b/src/ZoneTree/WAL/WriteAheadLogUtility.cs index 5d2a944..de23073 100644 --- a/src/ZoneTree/WAL/WriteAheadLogUtility.cs +++ b/src/ZoneTree/WAL/WriteAheadLogUtility.cs @@ -11,7 +11,7 @@ public static (IReadOnlyList keys, IReadOnlyList values) IReadOnlyList keys, IReadOnlyList values, IRefComparer comparer, - IsValueDeletedDelegate isValueDeleted) + IsValueDeletedDelegate isValueDeleted) { // WAL has unsorted data. Need to do following. // 1. stable sort keys and values based on keys @@ -32,7 +32,7 @@ public static (IReadOnlyList keys, IReadOnlyList values) { var value = list[i].Value; var key = list[i].Key; - if (isValueDeleted(value)) + if (isValueDeleted(key, value)) { // discard deleted items; while (++i < len) diff --git a/src/ZoneTree/ZoneTreeFactory.cs b/src/ZoneTree/ZoneTreeFactory.cs index 4854ed7..258b670 100644 --- a/src/ZoneTree/ZoneTreeFactory.cs +++ b/src/ZoneTree/ZoneTreeFactory.cs @@ -302,12 +302,12 @@ public ZoneTreeFactory } /// - /// Assigns value deletion query delegate. + /// Assigns key-value pair deletion query delegate. /// - /// The value deleted query delagate. + /// The key-value pair deleted query delagate. /// ZoneTree Factory public ZoneTreeFactory - SetIsValueDeletedDelegate(IsValueDeletedDelegate isValueDeleted) + SetIsValueDeletedDelegate(IsValueDeletedDelegate isValueDeleted) { Options.IsValueDeleted = isValueDeleted; return this; diff --git a/src/ZoneTree/docs/ZoneTree/README-NUGET.md b/src/ZoneTree/docs/ZoneTree/README-NUGET.md index 4fdb51e..fd7714d 100644 --- a/src/ZoneTree/docs/ZoneTree/README-NUGET.md +++ b/src/ZoneTree/docs/ZoneTree/README-NUGET.md @@ -226,7 +226,7 @@ In this example, `-1` is used as the deletion marker for integer values: using Tenray.ZoneTree; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int x) => x == -1) + .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int x) => x = -1) .OpenOrCreate(); @@ -250,8 +250,8 @@ struct MyDeletableValueType } using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in MyDeletableValueType x) => x.IsDeleted) - .SetMarkValueDeletedDelegate((ref MyDeletableValueType x) => x.IsDeleted = true) + .SetIsValueDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) + .SetMarkValueDeletedDelegate((ref MyDeletableValueType value) => value.IsDeleted = true) .OpenOrCreate(); // Deleting a key by setting the IsDeleted flag From c926bf35b569cbb507f49f7b50c6c09972684b5e Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sat, 7 Sep 2024 00:26:21 +0200 Subject: [PATCH 2/3] Rename IsValueDeleted delegate as IsDeleted. --- README.md | 4 +- src/ZoneTree.UnitTests/CountTests.cs | 2 +- .../FixedSizeKeyAndValueTests.cs | 2 +- src/ZoneTree.UnitTests/IteratorTests.cs | 6 +- .../MergeEmptySegmentsTest.cs | 6 +- .../OptimisticTransactionTests.cs | 8 +-- src/ZoneTree.UnitTests/TTLTests.cs | 2 +- src/ZoneTree/Collections/DictionaryWithWal.cs | 8 +-- .../Core/ZoneTree.BottomSegments.Merge.cs | 2 +- src/ZoneTree/Core/ZoneTree.Merge.cs | 2 +- src/ZoneTree/Core/ZoneTree.ReadWrite.cs | 14 ++-- src/ZoneTree/Core/ZoneTree.cs | 12 ++-- src/ZoneTree/Core/ZoneTreeIterator.cs | 8 +-- src/ZoneTree/Options/ZoneTreeOptions.cs | 10 +-- .../PresetTypes/ComponentsForKnownTypes.cs | 66 +++++++++---------- .../Segments/InMemory/MutableSegment.cs | 4 +- .../Transactional/OptimisticZoneTree.cs | 4 +- src/ZoneTree/WAL/WriteAheadLogUtility.cs | 4 +- src/ZoneTree/ZoneTreeFactory.cs | 6 +- src/ZoneTree/docs/ZoneTree/README-NUGET.md | 4 +- .../docs/ZoneTree/guide/TTL-support.md | 4 +- .../docs/ZoneTree/guide/quick-start.md | 4 +- 22 files changed, 91 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index a24e743..f7cd6c0 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ In this example, `-1` is used as the deletion marker for integer values: using Tenray.ZoneTree; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); @@ -251,7 +251,7 @@ struct MyDeletableValueType } using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) + .SetIsDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) .SetMarkValueDeletedDelegate((ref MyDeletableValueType value) => value.IsDeleted = true) .OpenOrCreate(); diff --git a/src/ZoneTree.UnitTests/CountTests.cs b/src/ZoneTree.UnitTests/CountTests.cs index cbc2f4f..685e354 100644 --- a/src/ZoneTree.UnitTests/CountTests.cs +++ b/src/ZoneTree.UnitTests/CountTests.cs @@ -19,7 +19,7 @@ public void CountRecordsDuringAMerge( Directory.Delete(dataPath, true); using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in string key, in int value) => value == -1) + .SetIsDeletedDelegate((in string key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int x) => x = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) diff --git a/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs b/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs index 6d18b59..24518bc 100644 --- a/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs +++ b/src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs @@ -312,7 +312,7 @@ static void ReloadIntIntTreeTestHelper(string dataPath, bool destroy) .SetWriteAheadLogDirectory(dataPath) .ConfigureWriteAheadLogOptions(x => x.WriteAheadLogMode = WriteAheadLogMode.Sync) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var n = 2000; diff --git a/src/ZoneTree.UnitTests/IteratorTests.cs b/src/ZoneTree.UnitTests/IteratorTests.cs index ba70de7..1501bc6 100644 --- a/src/ZoneTree.UnitTests/IteratorTests.cs +++ b/src/ZoneTree.UnitTests/IteratorTests.cs @@ -19,7 +19,7 @@ public void IntIntIterator() .SetMutableSegmentMaxItemCount(11) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 250; @@ -89,7 +89,7 @@ public void IntIntIteratorSeek() .SetMutableSegmentMaxItemCount(11) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 250; @@ -180,7 +180,7 @@ public void IntIntIteratorReflectNewInserts() .SetMutableSegmentMaxItemCount(250) .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); var a = 251; diff --git a/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs b/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs index 31b7339..d785338 100644 --- a/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs +++ b/src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs @@ -16,7 +16,7 @@ public void MergeEmptySegments( Directory.Delete(dataPath, true); using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in int value) => true) + .SetIsDeletedDelegate((in int key, in int value) => true) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) @@ -64,7 +64,7 @@ public void MergeDeletedSegments( var isRecordDeleted = false; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in int value) => isRecordDeleted) + .SetIsDeletedDelegate((in int key, in int value) => isRecordDeleted) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDataDirectory(dataPath) @@ -124,7 +124,7 @@ public void MergeDeletedBottomSegments( var isRecordDeleted = false; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in int value) => isRecordDeleted) + .SetIsDeletedDelegate((in int key, in int value) => isRecordDeleted) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .SetMutableSegmentMaxItemCount(100) .SetDiskSegmentMaxItemCount(250) diff --git a/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs b/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs index dc6f54f..2848767 100644 --- a/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs +++ b/src/ZoneTree.UnitTests/OptimisticTransactionTests.cs @@ -119,7 +119,7 @@ public void ReadCommittedTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); @@ -172,7 +172,7 @@ public void TransactionLogCompactionTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); @@ -219,7 +219,7 @@ public void TransactionLogCompactionWithSkipWriteRule(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); @@ -254,7 +254,7 @@ public void TransactionIsolationTest(int compactionThreshold) using var zoneTree = new ZoneTreeFactory() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreateTransactional(); diff --git a/src/ZoneTree.UnitTests/TTLTests.cs b/src/ZoneTree.UnitTests/TTLTests.cs index 5d61454..c909df2 100644 --- a/src/ZoneTree.UnitTests/TTLTests.cs +++ b/src/ZoneTree.UnitTests/TTLTests.cs @@ -17,7 +17,7 @@ public void TestTTL() .SetDataDirectory(dataPath) .SetWriteAheadLogDirectory(dataPath) .SetValueSerializer(new StructSerializer>()) - .SetIsValueDeletedDelegate((in int key, in TTLValue value) => value.IsExpired) + .SetIsDeletedDelegate((in int key, in TTLValue value) => value.IsExpired) .SetMarkValueDeletedDelegate(void (ref TTLValue value) => value.Expire()) .OpenOrCreate(); diff --git a/src/ZoneTree/Collections/DictionaryWithWal.cs b/src/ZoneTree/Collections/DictionaryWithWal.cs index f48618c..35940ca 100644 --- a/src/ZoneTree/Collections/DictionaryWithWal.cs +++ b/src/ZoneTree/Collections/DictionaryWithWal.cs @@ -28,7 +28,7 @@ public sealed class DictionaryWithWAL : IDisposable readonly IRefComparer Comparer; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsDeletedDelegate IsDeleted; readonly MarkValueDeletedDelegate MarkValueDeleted; @@ -54,7 +54,7 @@ public DictionaryWithWAL( ISerializer keySerializer, ISerializer valueSerializer, IRefComparer comparer, - IsValueDeletedDelegate isValueDeleted, + IsDeletedDelegate isDeleted, MarkValueDeletedDelegate markValueDeleted) { WriteAheadLogProvider = writeAheadLogProvider; @@ -63,7 +63,7 @@ public DictionaryWithWAL( .GetOrCreateWAL(segmentId, category, options, keySerializer, valueSerializer); SegmentId = segmentId; Category = category; - IsValueDeleted = isValueDeleted; + IsDeleted = isDeleted; MarkValueDeleted = markValueDeleted; LoadFromWriteAheadLog(); } @@ -91,7 +91,7 @@ void LoadFromWriteAheadLog() result.Keys, result.Values, Comparer, - IsValueDeleted); + IsDeleted); var len = newKeys.Count; for (var i = 0; i < len; ++i) { diff --git a/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs b/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs index 4d7c1c1..04d6e0c 100644 --- a/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs +++ b/src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs @@ -184,7 +184,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries if writeDeletedValues is false. - if (!writeDeletedValues && IsValueDeleted(minEntry.Key, minEntry.Value)) + if (!writeDeletedValues && IsDeleted(minEntry.Key, minEntry.Value)) { skipElement(); prevKey = minEntry.Key; diff --git a/src/ZoneTree/Core/ZoneTree.Merge.cs b/src/ZoneTree/Core/ZoneTree.Merge.cs index 5607144..1b14f18 100644 --- a/src/ZoneTree/Core/ZoneTree.Merge.cs +++ b/src/ZoneTree/Core/ZoneTree.Merge.cs @@ -230,7 +230,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries if bottom segments queue is empty. - if (!hasBottomSegments && IsValueDeleted(minEntry.Key, minEntry.Value)) + if (!hasBottomSegments && IsDeleted(minEntry.Key, minEntry.Value)) { skipElement(); prevKey = minEntry.Key; diff --git a/src/ZoneTree/Core/ZoneTree.ReadWrite.cs b/src/ZoneTree/Core/ZoneTree.ReadWrite.cs index f9e0cd5..1895297 100644 --- a/src/ZoneTree/Core/ZoneTree.ReadWrite.cs +++ b/src/ZoneTree/Core/ZoneTree.ReadWrite.cs @@ -11,7 +11,7 @@ public bool ContainsKey(in TKey key) if (MutableSegment.ContainsKey(key)) { if (MutableSegment.TryGet(key, out TValue value)) - return !IsValueDeleted(key, value); + return !IsDeleted(key, value); } return TryGetFromReadonlySegments(in key, out _); @@ -23,7 +23,7 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value) { if (segment.TryGet(key, out value)) { - return !IsValueDeleted(key, value); + return !IsDeleted(key, value); } } @@ -33,14 +33,14 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value) { if (DiskSegment.TryGet(key, out value)) { - return !IsValueDeleted(key, value); + return !IsDeleted(key, value); } foreach (var segment in BottomSegmentQueue) { if (segment.TryGet(key, out value)) { - return !IsValueDeleted(key, value); + return !IsDeleted(key, value); } } return false; @@ -56,7 +56,7 @@ public bool TryGet(in TKey key, out TValue value) { if (MutableSegment.TryGet(key, out value)) { - return !IsValueDeleted(key, value); + return !IsDeleted(key, value); } return TryGetFromReadonlySegments(in key, out value); } @@ -76,7 +76,7 @@ public bool TryGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDelegate< if (MutableSegment.TryGet(key, out value)) { - if (IsValueDeleted(key, value)) + if (IsDeleted(key, value)) return false; } else if (!TryGetFromReadonlySegments(in key, out value)) @@ -101,7 +101,7 @@ public bool TryAtomicGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDel { if (MutableSegment.TryGet(key, out value)) { - if (IsValueDeleted(key, value)) + if (IsDeleted(key, value)) return false; } else if (!TryGetFromReadonlySegments(in key, out value)) diff --git a/src/ZoneTree/Core/ZoneTree.cs b/src/ZoneTree/Core/ZoneTree.cs index 73d98a7..ba966f2 100644 --- a/src/ZoneTree/Core/ZoneTree.cs +++ b/src/ZoneTree/Core/ZoneTree.cs @@ -26,7 +26,7 @@ public sealed partial class ZoneTree : IZoneTree, IZ readonly MaxHeapEntryRefComparer MaxHeapEntryComparer; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsDeletedDelegate IsDeleted; readonly SingleProducerSingleConsumerQueue> ReadOnlySegmentQueue = new(); @@ -142,7 +142,7 @@ public ZoneTree(ZoneTreeOptions options) MaxHeapEntryComparer = new MaxHeapEntryRefComparer(options.Comparer); MutableSegment = new MutableSegment( options, IncrementalIdProvider.NextId(), new IncrementalIdProvider()); - IsValueDeleted = options.IsValueDeleted; + IsDeleted = options.IsDeleted; FillZoneTreeMeta(); MetaWal.SaveMetaData( ZoneTreeMeta, @@ -178,7 +178,7 @@ long maximumSegmentId ReadOnlySegmentQueue.Enqueue(ros); foreach (var bs in bottomSegments.Reverse()) BottomSegmentQueue.Enqueue(bs); - IsValueDeleted = options.IsValueDeleted; + IsDeleted = options.IsDeleted; } void FillZoneTreeMeta() @@ -306,15 +306,15 @@ public long Count() { var key = iterator.CurrentKey; var hasKey = diskSegment.ContainsKey(key); - var isValueDeleted = IsValueDeleted(key, iterator.CurrentValue); + var isDeleted = IsDeleted(key, iterator.CurrentValue); if (hasKey) { - if (isValueDeleted) + if (isDeleted) --count; } else { - if (!isValueDeleted) + if (!isDeleted) ++count; } } diff --git a/src/ZoneTree/Core/ZoneTreeIterator.cs b/src/ZoneTree/Core/ZoneTreeIterator.cs index 945cb17..2c6f673 100644 --- a/src/ZoneTree/Core/ZoneTreeIterator.cs +++ b/src/ZoneTree/Core/ZoneTreeIterator.cs @@ -18,7 +18,7 @@ public sealed class ZoneTreeIterator : IZoneTreeIterator> SeekableIterators; - readonly IsValueDeletedDelegate IsValueDeleted; + readonly IsDeletedDelegate IsDeleted; readonly IRefComparer Comparer; @@ -85,7 +85,7 @@ public ZoneTreeIterator( bool includeDiskSegment, bool includeBottomSegments) { - IsValueDeleted = options.IsValueDeleted; + IsDeleted = options.IsDeleted; Comparer = options.Comparer; ZoneTree = zoneTree; HeapEntryComparer = heapEntryComparer; @@ -280,7 +280,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries. - if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Key, minEntry.Value)) + if (!IncludeDeletedRecords && IsDeleted(minEntry.Key, minEntry.Value)) { skipElement(); PrevKey = minEntry.Key; @@ -330,7 +330,7 @@ void skipElement() minSegmentIndex = minEntry.SegmentIndex; // ignore deleted entries. - if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Key, minEntry.Value)) + if (!IncludeDeletedRecords && IsDeleted(minEntry.Key, minEntry.Value)) { skipElement(); PrevKey = minEntry.Key; diff --git a/src/ZoneTree/Options/ZoneTreeOptions.cs b/src/ZoneTree/Options/ZoneTreeOptions.cs index c93580f..4a23c17 100644 --- a/src/ZoneTree/Options/ZoneTreeOptions.cs +++ b/src/ZoneTree/Options/ZoneTreeOptions.cs @@ -17,7 +17,7 @@ namespace Tenray.ZoneTree.Options; /// Key to be queried /// Value to be queried /// true if the key-value pair is deleted, false otherwise -public delegate bool IsValueDeletedDelegate(in TKey key, in TValue value); +public delegate bool IsDeletedDelegate(in TKey key, in TValue value); /// /// A delegate to mark a value deleted. @@ -66,7 +66,7 @@ public sealed class ZoneTreeOptions /// /// Delegate to query key-value pair deletion state. /// - public IsValueDeletedDelegate IsValueDeleted { get; set; } + public IsDeletedDelegate IsDeleted { get; set; } /// /// Delegate to mark value deleted. @@ -224,8 +224,8 @@ public void Validate() /// public void CreateDefaultDeleteDelegates() { - if (IsValueDeleted == null) - IsValueDeleted = ComponentsForKnownTypes.GetIsValueDeleted(); + if (IsDeleted == null) + IsDeleted = ComponentsForKnownTypes.GetIsDeleted(); if (MarkValueDeleted == null) MarkValueDeleted = ComponentsForKnownTypes.GetMarkValueDeleted(); } @@ -246,7 +246,7 @@ static bool IsAssignableToNull(Type type) /// public void DisableDeletion() { - IsValueDeleted = (in TKey _, in TValue _) => false; + IsDeleted = (in TKey _, in TValue _) => false; MarkValueDeleted = (ref TValue _) => { }; } } diff --git a/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs b/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs index 3507d5b..205b653 100644 --- a/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs +++ b/src/ZoneTree/PresetTypes/ComponentsForKnownTypes.cs @@ -94,21 +94,21 @@ public static ISerializer GetSerializer() } // Specific methods for checking if certain primitive types are considered deleted - static bool IsValueDeletedByte(in TKey key, in byte value) => value == default; - static bool IsValueDeletedChar(in TKey key, in char value) => value == default; - static bool IsValueDeletedDateTime(in TKey key, in DateTime value) => value == default; - static bool IsValueDeletedDecimal(in TKey key, in decimal value) => value == default; - static bool IsValueDeletedDouble(in TKey key, in double value) => value == default; - static bool IsValueDeletedShort(in TKey key, in short value) => value == default; - static bool IsValueDeletedUShort(in TKey key, in ushort value) => value == default; - static bool IsValueDeletedInt(in TKey key, in int value) => value == default; - static bool IsValueDeletedUInt(in TKey key, in uint value) => value == default; - static bool IsValueDeletedLong(in TKey key, in long value) => value == default; - static bool IsValueDeletedULong(in TKey key, in ulong value) => value == default; - static bool IsValueDeletedGuid(in TKey key, in Guid value) => value == default; - static bool IsValueDeletedMemoryByte(in TKey key, in Memory value) => value.Length == 0; - static bool IsValueDeletedReferenceType(in TKey key, in TValue value) => ReferenceEquals(value, default(TValue)); - static bool IsValueDeletedDefault(in TKey key, in TValue value) => EqualityComparer.Default.Equals(value, default); + static bool IsDeletedByte(in TKey key, in byte value) => value == default; + static bool IsDeletedChar(in TKey key, in char value) => value == default; + static bool IsDeletedDateTime(in TKey key, in DateTime value) => value == default; + static bool IsDeletedDecimal(in TKey key, in decimal value) => value == default; + static bool IsDeletedDouble(in TKey key, in double value) => value == default; + static bool IsDeletedShort(in TKey key, in short value) => value == default; + static bool IsDeletedUShort(in TKey key, in ushort value) => value == default; + static bool IsDeletedInt(in TKey key, in int value) => value == default; + static bool IsDeletedUInt(in TKey key, in uint value) => value == default; + static bool IsDeletedLong(in TKey key, in long value) => value == default; + static bool IsDeletedULong(in TKey key, in ulong value) => value == default; + static bool IsDeletedGuid(in TKey key, in Guid value) => value == default; + static bool IsDeletedMemoryByte(in TKey key, in Memory value) => value.Length == 0; + static bool IsDeletedReferenceType(in TKey key, in TValue value) => ReferenceEquals(value, default(TValue)); + static bool IsDeletedDefault(in TKey key, in TValue value) => EqualityComparer.Default.Equals(value, default); static void MarkValueDeletedDefault(ref TValue value) { value = default; } @@ -118,32 +118,32 @@ public static ISerializer GetSerializer() /// The type of the key. /// The type of the value. /// A delegate that checks if the value is considered deleted. - public static IsValueDeletedDelegate GetIsValueDeleted() + public static IsDeletedDelegate GetIsDeleted() { - static IsValueDeletedDelegate Cast(object method) => - (IsValueDeletedDelegate)method; + static IsDeletedDelegate Cast(object method) => + (IsDeletedDelegate)method; TValue value = default; var result = value switch { - byte => Cast(new IsValueDeletedDelegate(IsValueDeletedByte)), - char => Cast(new IsValueDeletedDelegate(IsValueDeletedChar)), - DateTime => Cast(new IsValueDeletedDelegate(IsValueDeletedDateTime)), - decimal => Cast(new IsValueDeletedDelegate(IsValueDeletedDecimal)), - double => Cast(new IsValueDeletedDelegate(IsValueDeletedDouble)), - short => Cast(new IsValueDeletedDelegate(IsValueDeletedShort)), - ushort => Cast(new IsValueDeletedDelegate(IsValueDeletedUShort)), - int => Cast(new IsValueDeletedDelegate(IsValueDeletedInt)), - uint => Cast(new IsValueDeletedDelegate(IsValueDeletedUInt)), - long => Cast(new IsValueDeletedDelegate(IsValueDeletedLong)), - ulong => Cast(new IsValueDeletedDelegate(IsValueDeletedULong)), - Guid => Cast(new IsValueDeletedDelegate(IsValueDeletedGuid)), - _ => IsValueDeletedDefault + byte => Cast(new IsDeletedDelegate(IsDeletedByte)), + char => Cast(new IsDeletedDelegate(IsDeletedChar)), + DateTime => Cast(new IsDeletedDelegate(IsDeletedDateTime)), + decimal => Cast(new IsDeletedDelegate(IsDeletedDecimal)), + double => Cast(new IsDeletedDelegate(IsDeletedDouble)), + short => Cast(new IsDeletedDelegate(IsDeletedShort)), + ushort => Cast(new IsDeletedDelegate(IsDeletedUShort)), + int => Cast(new IsDeletedDelegate(IsDeletedInt)), + uint => Cast(new IsDeletedDelegate(IsDeletedUInt)), + long => Cast(new IsDeletedDelegate(IsDeletedLong)), + ulong => Cast(new IsDeletedDelegate(IsDeletedULong)), + Guid => Cast(new IsDeletedDelegate(IsDeletedGuid)), + _ => IsDeletedDefault }; if (typeof(TValue) == typeof(Memory)) - result = Cast(new IsValueDeletedDelegate>(IsValueDeletedMemoryByte)); + result = Cast(new IsDeletedDelegate>(IsDeletedMemoryByte)); if (RuntimeHelpers.IsReferenceOrContainsReferences()) - return IsValueDeletedReferenceType; + return IsDeletedReferenceType; return result; } diff --git a/src/ZoneTree/Segments/InMemory/MutableSegment.cs b/src/ZoneTree/Segments/InMemory/MutableSegment.cs index 359517d..6009ab4 100644 --- a/src/ZoneTree/Segments/InMemory/MutableSegment.cs +++ b/src/ZoneTree/Segments/InMemory/MutableSegment.cs @@ -118,7 +118,7 @@ void LoadLogEntriesWithGarbageCollection( var distinctKeys = new BTree(Options.Comparer, Collections.BTree.Lock.BTreeLockMode.NoLock); - var isValueDeleted = Options.IsValueDeleted; + var isDeleted = Options.IsDeleted; for (var i = keys.Count - 1; i >= 0; --i) { var key = keys[i]; @@ -126,7 +126,7 @@ void LoadLogEntriesWithGarbageCollection( continue; var value = values[i]; distinctKeys.Upsert(in key, 1, out _); - if (isValueDeleted(in key, in value)) + if (isDeleted(in key, in value)) { continue; } diff --git a/src/ZoneTree/Transactional/OptimisticZoneTree.cs b/src/ZoneTree/Transactional/OptimisticZoneTree.cs index aead373..57b45ca 100644 --- a/src/ZoneTree/Transactional/OptimisticZoneTree.cs +++ b/src/ZoneTree/Transactional/OptimisticZoneTree.cs @@ -323,7 +323,7 @@ public bool ReadCommittedContainsKey(in TKey key, long currentTransactionId = -1 Debug.Assert(state != TransactionState.Aborted); - if (Options.IsValueDeleted(in key, history.Value1)) + if (Options.IsDeleted(in key, history.Value1)) { return false; } @@ -374,7 +374,7 @@ public bool ReadCommittedTryGet(in TKey key, out TValue value, long currentTrans Debug.Assert(state != TransactionState.Aborted); - if (Options.IsValueDeleted(in key, history.Value1)) + if (Options.IsDeleted(in key, history.Value1)) { value = default; return false; diff --git a/src/ZoneTree/WAL/WriteAheadLogUtility.cs b/src/ZoneTree/WAL/WriteAheadLogUtility.cs index de23073..16a9105 100644 --- a/src/ZoneTree/WAL/WriteAheadLogUtility.cs +++ b/src/ZoneTree/WAL/WriteAheadLogUtility.cs @@ -11,7 +11,7 @@ public static (IReadOnlyList keys, IReadOnlyList values) IReadOnlyList keys, IReadOnlyList values, IRefComparer comparer, - IsValueDeletedDelegate isValueDeleted) + IsDeletedDelegate isDeleted) { // WAL has unsorted data. Need to do following. // 1. stable sort keys and values based on keys @@ -32,7 +32,7 @@ public static (IReadOnlyList keys, IReadOnlyList values) { var value = list[i].Value; var key = list[i].Key; - if (isValueDeleted(key, value)) + if (isDeleted(key, value)) { // discard deleted items; while (++i < len) diff --git a/src/ZoneTree/ZoneTreeFactory.cs b/src/ZoneTree/ZoneTreeFactory.cs index 258b670..0cb3533 100644 --- a/src/ZoneTree/ZoneTreeFactory.cs +++ b/src/ZoneTree/ZoneTreeFactory.cs @@ -304,12 +304,12 @@ public ZoneTreeFactory /// /// Assigns key-value pair deletion query delegate. /// - /// The key-value pair deleted query delagate. + /// The key-value pair deleted query delagate. /// ZoneTree Factory public ZoneTreeFactory - SetIsValueDeletedDelegate(IsValueDeletedDelegate isValueDeleted) + SetIsDeletedDelegate(IsDeletedDelegate isDeleted) { - Options.IsValueDeleted = isValueDeleted; + Options.IsDeleted = isDeleted; return this; } diff --git a/src/ZoneTree/docs/ZoneTree/README-NUGET.md b/src/ZoneTree/docs/ZoneTree/README-NUGET.md index fd7714d..d4a581e 100644 --- a/src/ZoneTree/docs/ZoneTree/README-NUGET.md +++ b/src/ZoneTree/docs/ZoneTree/README-NUGET.md @@ -226,7 +226,7 @@ In this example, `-1` is used as the deletion marker for integer values: using Tenray.ZoneTree; using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in int value) => value == -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) .SetMarkValueDeletedDelegate((ref int x) => x = -1) .OpenOrCreate(); @@ -250,7 +250,7 @@ struct MyDeletableValueType } using var zoneTree = new ZoneTreeFactory() - .SetIsValueDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) + .SetIsDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) .SetMarkValueDeletedDelegate((ref MyDeletableValueType value) => value.IsDeleted = true) .OpenOrCreate(); diff --git a/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md b/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md index 65299f4..ca02013 100644 --- a/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md +++ b/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md @@ -11,7 +11,7 @@ Following code demonstrates a TTL ZoneTree database with absolute expiration. ```C# using var zoneTree = new ZoneTreeFactory>() .SetValueSerializer(new StructSerializer>()) - .SetIsValueDeletedDelegate((in TTLValue x) => x.IsExpired) + .SetIsDeletedDelegate((in TTLValue x) => x.IsExpired) .SetMarkValueDeletedDelegate(void (ref TTLValue x) => x.Expire()) .OpenOrCreate(); @@ -26,7 +26,7 @@ Following code demonstrates a TTL ZoneTree database with sliding expiration. ```C# using var zoneTree = new ZoneTreeFactory>() .SetValueSerializer(new StructSerializer>()) - .SetIsValueDeletedDelegate((in TTLValue x) => x.IsExpired) + .SetIsDeletedDelegate((in TTLValue x) => x.IsExpired) .SetMarkValueDeletedDelegate(void (ref TTLValue x) => x.Expire()) .OpenOrCreate(); diff --git a/src/ZoneTree/docs/ZoneTree/guide/quick-start.md b/src/ZoneTree/docs/ZoneTree/guide/quick-start.md index 771b89a..c1ec566 100644 --- a/src/ZoneTree/docs/ZoneTree/guide/quick-start.md +++ b/src/ZoneTree/docs/ZoneTree/guide/quick-start.md @@ -105,7 +105,7 @@ In this example, -1 is used as the deletion marker for integer values: ```c# using var zoneTree = new ZoneTreeFactory() // Additional stuff goes here - .SetIsValueDeletedDelegate((in int x) => x == -1) + .SetIsDeletedDelegate((in int x) => x == -1) .SetMarkValueDeletedDelegate((ref int x) => x = -1) .OpenOrCreate(); ``` @@ -116,7 +116,7 @@ Alternatively, if you're using a custom struct to manage deletions, you can conf ```c# using var zoneTree = new ZoneTreeFactory() // Additional stuff goes here - .SetIsValueDeletedDelegate((in MyDeletableValueType x) => x.IsDeleted) + .SetIsDeletedDelegate((in MyDeletableValueType x) => x.IsDeleted) .SetMarkValueDeletedDelegate((ref MyDeletableValueType x) => x.IsDeleted = true) .OpenOrCreate(); ``` From a5abf3b77047c4073b2246baf244e54345d94759 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sat, 7 Sep 2024 00:31:38 +0200 Subject: [PATCH 3/3] Update docs. --- src/ZoneTree/docs/ZoneTree/guide/TTL-support.md | 8 ++++---- src/ZoneTree/docs/ZoneTree/guide/quick-start.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md b/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md index ca02013..edb1ee6 100644 --- a/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md +++ b/src/ZoneTree/docs/ZoneTree/guide/TTL-support.md @@ -11,8 +11,8 @@ Following code demonstrates a TTL ZoneTree database with absolute expiration. ```C# using var zoneTree = new ZoneTreeFactory>() .SetValueSerializer(new StructSerializer>()) - .SetIsDeletedDelegate((in TTLValue x) => x.IsExpired) - .SetMarkValueDeletedDelegate(void (ref TTLValue x) => x.Expire()) + .SetIsDeletedDelegate((in int key, in TTLValue value) => value.IsExpired) + .SetMarkValueDeletedDelegate(void (ref TTLValue value) => value.Expire()) .OpenOrCreate(); var expiration = DateTime.UtcNow.AddSeconds(30); @@ -26,8 +26,8 @@ Following code demonstrates a TTL ZoneTree database with sliding expiration. ```C# using var zoneTree = new ZoneTreeFactory>() .SetValueSerializer(new StructSerializer>()) - .SetIsDeletedDelegate((in TTLValue x) => x.IsExpired) - .SetMarkValueDeletedDelegate(void (ref TTLValue x) => x.Expire()) + .SetIsDeletedDelegate((in int key, in TTLValue value) => value.IsExpired) + .SetMarkValueDeletedDelegate(void (ref TTLValue value) => value.Expire()) .OpenOrCreate(); var expiration = DateTime.UtcNow.AddSeconds(30); diff --git a/src/ZoneTree/docs/ZoneTree/guide/quick-start.md b/src/ZoneTree/docs/ZoneTree/guide/quick-start.md index c1ec566..e424c9c 100644 --- a/src/ZoneTree/docs/ZoneTree/guide/quick-start.md +++ b/src/ZoneTree/docs/ZoneTree/guide/quick-start.md @@ -105,8 +105,8 @@ In this example, -1 is used as the deletion marker for integer values: ```c# using var zoneTree = new ZoneTreeFactory() // Additional stuff goes here - .SetIsDeletedDelegate((in int x) => x == -1) - .SetMarkValueDeletedDelegate((ref int x) => x = -1) + .SetIsDeletedDelegate((in int key, in int value) => value == -1) + .SetMarkValueDeletedDelegate((ref int value) => value = -1) .OpenOrCreate(); ``` @@ -116,8 +116,8 @@ Alternatively, if you're using a custom struct to manage deletions, you can conf ```c# using var zoneTree = new ZoneTreeFactory() // Additional stuff goes here - .SetIsDeletedDelegate((in MyDeletableValueType x) => x.IsDeleted) - .SetMarkValueDeletedDelegate((ref MyDeletableValueType x) => x.IsDeleted = true) + .SetIsDeletedDelegate((in int key, in MyDeletableValueType value) => value.IsDeleted) + .SetMarkValueDeletedDelegate((ref MyDeletableValueType value) => value.IsDeleted = true) .OpenOrCreate(); ```