Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide key in IsDeleted delegate to support TTL based on keys #92

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, int>()
.SetIsValueDeletedDelegate((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();

// Deleting a key by setting its value to -1
Expand All @@ -251,8 +251,8 @@ struct MyDeletableValueType
}

using var zoneTree = new ZoneTreeFactory<int, MyDeletableValueType>()
.SetIsValueDeletedDelegate((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();

// Deleting a key by setting the IsDeleted flag
Expand Down
2 changes: 1 addition & 1 deletion src/ZoneTree.UnitTests/CountTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public void CountRecordsDuringAMerge(
Directory.Delete(dataPath, true);

using var zoneTree = new ZoneTreeFactory<string, int>()
.SetIsValueDeletedDelegate((in int x) => x == -1)
.SetIsDeletedDelegate((in string key, in int value) => value == -1)
.SetMarkValueDeletedDelegate((ref int x) => x = -1)
.SetMutableSegmentMaxItemCount(100)
.SetDataDirectory(dataPath)
Expand Down
4 changes: 2 additions & 2 deletions src/ZoneTree.UnitTests/FixedSizeKeyAndValueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
.SetIsDeletedDelegate((in int key, in int value) => value == -1)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.OpenOrCreate();
var n = 2000;
var deleted = new HashSet<int>() { 11, 99, 273, 200, 333, 441, 203, 499, 666 };
Expand Down
12 changes: 6 additions & 6 deletions src/ZoneTree.UnitTests/IteratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
.SetIsDeletedDelegate((in int key, in int value) => value == -1)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.OpenOrCreate();
var a = 250;
var b = 500;
Expand Down Expand Up @@ -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)
.SetIsDeletedDelegate((in int key, in int value) => value == -1)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.OpenOrCreate();
var a = 250;
var b = 500;
Expand Down Expand Up @@ -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)
.SetIsDeletedDelegate((in int key, in int value) => value == -1)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.OpenOrCreate();
var a = 251;
var b = 500;
Expand Down
12 changes: 6 additions & 6 deletions src/ZoneTree.UnitTests/MergeEmptySegmentsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public void MergeEmptySegments(
Directory.Delete(dataPath, true);

using var zoneTree = new ZoneTreeFactory<int, int>()
.SetIsValueDeletedDelegate((in int x) => true)
.SetMarkValueDeletedDelegate((ref int x) => x = -1)
.SetIsDeletedDelegate((in int key, in int value) => true)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.SetMutableSegmentMaxItemCount(100)
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
Expand Down Expand Up @@ -64,8 +64,8 @@ public void MergeDeletedSegments(

var isRecordDeleted = false;
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetIsValueDeletedDelegate((in int x) => isRecordDeleted)
.SetMarkValueDeletedDelegate((ref int x) => x = -1)
.SetIsDeletedDelegate((in int key, in int value) => isRecordDeleted)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.SetMutableSegmentMaxItemCount(100)
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
Expand Down Expand Up @@ -124,8 +124,8 @@ public void MergeDeletedBottomSegments(

var isRecordDeleted = false;
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetIsValueDeletedDelegate((in int x) => isRecordDeleted)
.SetMarkValueDeletedDelegate((ref int x) => x = -1)
.SetIsDeletedDelegate((in int key, in int value) => isRecordDeleted)
.SetMarkValueDeletedDelegate((ref int value) => value = -1)
.SetMutableSegmentMaxItemCount(100)
.SetDiskSegmentMaxItemCount(250)
.SetDataDirectory(dataPath)
Expand Down
16 changes: 8 additions & 8 deletions src/ZoneTree.UnitTests/OptimisticTransactionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public void ReadCommittedTest(int compactionThreshold)
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
.SetIsValueDeletedDelegate((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)
.OpenOrCreateTransactional();

zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold;
Expand Down Expand Up @@ -172,8 +172,8 @@ public void TransactionLogCompactionTest(int compactionThreshold)
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
.SetIsValueDeletedDelegate((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)
.OpenOrCreateTransactional();

zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold;
Expand Down Expand Up @@ -219,8 +219,8 @@ public void TransactionLogCompactionWithSkipWriteRule(int compactionThreshold)
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
.SetIsValueDeletedDelegate((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)
.OpenOrCreateTransactional();

zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold;
Expand Down Expand Up @@ -254,8 +254,8 @@ public void TransactionIsolationTest(int compactionThreshold)
using var zoneTree = new ZoneTreeFactory<int, int>()
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
.SetIsValueDeletedDelegate((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)
.OpenOrCreateTransactional();

zoneTree.Maintenance.TransactionLog.CompactionThreshold = compactionThreshold;
Expand Down
8 changes: 4 additions & 4 deletions src/ZoneTree.UnitTests/TTLTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public void TestTTL()
.SetDataDirectory(dataPath)
.SetWriteAheadLogDirectory(dataPath)
.SetValueSerializer(new StructSerializer<TTLValue<int>>())
.SetIsValueDeletedDelegate((in TTLValue<int> x) => x.IsExpired)
.SetMarkValueDeletedDelegate(void (ref TTLValue<int> x) => x.Expire())
.SetIsDeletedDelegate((in int key, in TTLValue<int> value) => value.IsExpired)
.SetMarkValueDeletedDelegate(void (ref TTLValue<int> value) => value.Expire())
.OpenOrCreate();

zoneTree.Upsert(5, new TTLValue<int>(99, DateTime.UtcNow.AddMilliseconds(300)));
Expand All @@ -33,8 +33,8 @@ public void TestTTL()
Thread.Sleep(150);
f1 = zoneTree.TryGetAndUpdate(
5,
out v1,
bool (ref TTLValue<int> v) =>
out v1,
bool (ref TTLValue<int> v) =>
v.SlideExpiration(TimeSpan.FromMilliseconds(300)));
Thread.Sleep(450); // initial expiration (300) + slided expiration (300) - Thread.Sleep(150)
f2 = zoneTree.TryGetAndUpdate(
Expand Down
8 changes: 4 additions & 4 deletions src/ZoneTree/Collections/DictionaryWithWal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public sealed class DictionaryWithWAL<TKey, TValue> : IDisposable

readonly IRefComparer<TKey> Comparer;

readonly IsValueDeletedDelegate<TValue> IsValueDeleted;
readonly IsDeletedDelegate<TKey, TValue> IsDeleted;

readonly MarkValueDeletedDelegate<TValue> MarkValueDeleted;

Expand All @@ -54,7 +54,7 @@ public DictionaryWithWAL(
ISerializer<TKey> keySerializer,
ISerializer<TValue> valueSerializer,
IRefComparer<TKey> comparer,
IsValueDeletedDelegate<TValue> isValueDeleted,
IsDeletedDelegate<TKey, TValue> isDeleted,
MarkValueDeletedDelegate<TValue> markValueDeleted)
{
WriteAheadLogProvider = writeAheadLogProvider;
Expand All @@ -63,7 +63,7 @@ public DictionaryWithWAL(
.GetOrCreateWAL(segmentId, category, options, keySerializer, valueSerializer);
SegmentId = segmentId;
Category = category;
IsValueDeleted = isValueDeleted;
IsDeleted = isDeleted;
MarkValueDeleted = markValueDeleted;
LoadFromWriteAheadLog();
}
Expand Down Expand Up @@ -91,7 +91,7 @@ void LoadFromWriteAheadLog()
result.Keys,
result.Values,
Comparer,
IsValueDeleted);
IsDeleted);
var len = newKeys.Count;
for (var i = 0; i < len; ++i)
{
Expand Down
2 changes: 1 addition & 1 deletion src/ZoneTree/Core/ZoneTree.BottomSegments.Merge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void skipElement()
minSegmentIndex = minEntry.SegmentIndex;

// ignore deleted entries if writeDeletedValues is false.
if (!writeDeletedValues && IsValueDeleted(minEntry.Value))
if (!writeDeletedValues && IsDeleted(minEntry.Key, minEntry.Value))
{
skipElement();
prevKey = minEntry.Key;
Expand Down
2 changes: 1 addition & 1 deletion src/ZoneTree/Core/ZoneTree.Merge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 && IsDeleted(minEntry.Key, minEntry.Value))
{
skipElement();
prevKey = minEntry.Key;
Expand Down
14 changes: 7 additions & 7 deletions src/ZoneTree/Core/ZoneTree.ReadWrite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 !IsDeleted(key, value);
}

return TryGetFromReadonlySegments(in key, out _);
Expand All @@ -23,7 +23,7 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value)
{
if (segment.TryGet(key, out value))
{
return !IsValueDeleted(value);
return !IsDeleted(key, value);
}
}

Expand All @@ -33,14 +33,14 @@ bool TryGetFromReadonlySegments(in TKey key, out TValue value)
{
if (DiskSegment.TryGet(key, out value))
{
return !IsValueDeleted(value);
return !IsDeleted(key, value);
}

foreach (var segment in BottomSegmentQueue)
{
if (segment.TryGet(key, out value))
{
return !IsValueDeleted(value);
return !IsDeleted(key, value);
}
}
return false;
Expand All @@ -56,7 +56,7 @@ public bool TryGet(in TKey key, out TValue value)
{
if (MutableSegment.TryGet(key, out value))
{
return !IsValueDeleted(value);
return !IsDeleted(key, value);
}
return TryGetFromReadonlySegments(in key, out value);
}
Expand All @@ -76,7 +76,7 @@ public bool TryGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDelegate<

if (MutableSegment.TryGet(key, out value))
{
if (IsValueDeleted(value))
if (IsDeleted(key, value))
return false;
}
else if (!TryGetFromReadonlySegments(in key, out value))
Expand All @@ -101,7 +101,7 @@ public bool TryAtomicGetAndUpdate(in TKey key, out TValue value, ValueUpdaterDel
{
if (MutableSegment.TryGet(key, out value))
{
if (IsValueDeleted(value))
if (IsDeleted(key, value))
return false;
}
else if (!TryGetFromReadonlySegments(in key, out value))
Expand Down
15 changes: 8 additions & 7 deletions src/ZoneTree/Core/ZoneTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public sealed partial class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZ

readonly MaxHeapEntryRefComparer<TKey, TValue> MaxHeapEntryComparer;

readonly IsValueDeletedDelegate<TValue> IsValueDeleted;
readonly IsDeletedDelegate<TKey, TValue> IsDeleted;

readonly SingleProducerSingleConsumerQueue<IReadOnlySegment<TKey, TValue>> ReadOnlySegmentQueue = new();

Expand Down Expand Up @@ -142,7 +142,7 @@ public ZoneTree(ZoneTreeOptions<TKey, TValue> options)
MaxHeapEntryComparer = new MaxHeapEntryRefComparer<TKey, TValue>(options.Comparer);
MutableSegment = new MutableSegment<TKey, TValue>(
options, IncrementalIdProvider.NextId(), new IncrementalIdProvider());
IsValueDeleted = options.IsValueDeleted;
IsDeleted = options.IsDeleted;
FillZoneTreeMeta();
MetaWal.SaveMetaData(
ZoneTreeMeta,
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -304,16 +304,17 @@ 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 isDeleted = IsDeleted(key, iterator.CurrentValue);
if (hasKey)
{
if (isValueDeleted)
if (isDeleted)
--count;
}
else
{
if (!isValueDeleted)
if (!isDeleted)
++count;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/ZoneTree/Core/ZoneTreeIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public sealed class ZoneTreeIterator<TKey, TValue> : IZoneTreeIterator<TKey, TVa

IReadOnlyList<ISeekableIterator<TKey, TValue>> SeekableIterators;

readonly IsValueDeletedDelegate<TValue> IsValueDeleted;
readonly IsDeletedDelegate<TKey, TValue> IsDeleted;

readonly IRefComparer<TKey> Comparer;

Expand Down Expand Up @@ -85,7 +85,7 @@ public ZoneTreeIterator(
bool includeDiskSegment,
bool includeBottomSegments)
{
IsValueDeleted = options.IsValueDeleted;
IsDeleted = options.IsDeleted;
Comparer = options.Comparer;
ZoneTree = zoneTree;
HeapEntryComparer = heapEntryComparer;
Expand Down Expand Up @@ -280,7 +280,7 @@ void skipElement()
minSegmentIndex = minEntry.SegmentIndex;

// ignore deleted entries.
if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Value))
if (!IncludeDeletedRecords && IsDeleted(minEntry.Key, minEntry.Value))
{
skipElement();
PrevKey = minEntry.Key;
Expand Down Expand Up @@ -330,7 +330,7 @@ void skipElement()
minSegmentIndex = minEntry.SegmentIndex;

// ignore deleted entries.
if (!IncludeDeletedRecords && IsValueDeleted(minEntry.Value))
if (!IncludeDeletedRecords && IsDeleted(minEntry.Key, minEntry.Value))
{
skipElement();
PrevKey = minEntry.Key;
Expand Down
4 changes: 2 additions & 2 deletions src/ZoneTree/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<Authors>Ahmed Yasin Koculu</Authors>
<PackageId>ZoneTree</PackageId>
<Title>ZoneTree</Title>
<ProductVersion>1.8.0.0</ProductVersion>
<Version>1.8.0.0</Version>
<ProductVersion>1.8.1.0</ProductVersion>
<Version>1.8.1.0</Version>
<Authors>Ahmed Yasin Koculu</Authors>
<AssemblyTitle>ZoneTree</AssemblyTitle>
<Description>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.</Description>
Expand Down
Loading
Loading