Adds read-only mode.

This commit is contained in:
Ahmed Yasin Koculu
2022-08-16 23:31:44 +02:00
parent ab939ecd6d
commit d7aa5dfcb0
7 changed files with 63 additions and 9 deletions
+8 -6
View File
@@ -24,16 +24,18 @@ public partial class BTree<TKey, TValue>
volatile LeafNode LastLeafNode;
public readonly IRefComparer<TKey> Comparer;
volatile int _length;
public int Length => _length;
public readonly BTreeLockMode LockMode;
public IIncrementalIdProvider OpIndexProvider { get; }
public bool IsReadOnly { get; set; }
volatile bool _isReadOnly;
public bool IsReadOnly { get => _isReadOnly; set => _isReadOnly = value; }
public BTree(
IRefComparer<TKey> comparer,
@@ -62,7 +64,7 @@ public partial class BTree<TKey, TValue>
ILocker GetNodeLocker() => LockMode switch
{
BTreeLockMode.TopLevelMonitor or
BTreeLockMode.TopLevelReaderWriter or
BTreeLockMode.TopLevelReaderWriter or
BTreeLockMode.NoLock => new NoLock(),
BTreeLockMode.NodeLevelMonitor => new MonitorLock(),
@@ -129,7 +131,7 @@ public partial class BTree<TKey, TValue>
var iterator = GetFrozenLeafNode(key).GetFrozenIterator();
return iterator.SeekFirstKeyGreaterOrEqual(Comparer, in key);
}
public NodeIterator GetFirstIterator()
{
try
@@ -166,7 +168,7 @@ public partial class BTree<TKey, TValue>
return LastLeafNode.GetFrozenIterator();
}
public void SetNextOpIndex(long nextId)
public void SetNextOpIndex(long nextId)
=> OpIndexProvider.SetNextId(nextId);
public long GetLastOpIndex()
+20 -1
View File
@@ -1,8 +1,8 @@
#undef TRACE_MERGE
using System.Collections.Concurrent;
using System.Diagnostics;
using Tenray.ZoneTree.Collections;
using Tenray.ZoneTree.Exceptions;
using Tenray.ZoneTree.Segments;
using Tenray.ZoneTree.Segments.Disk;
@@ -95,6 +95,10 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public event ZoneTreeIsDisposing<TKey, TValue> OnZoneTreeIsDisposing;
volatile bool _isReadOnly;
public bool IsReadOnly { get => _isReadOnly; set => _isReadOnly = value; }
public ZoneTree(ZoneTreeOptions<TKey, TValue> options)
{
options.WriteAheadLogProvider.InitCategory(SegmentWalCategory);
@@ -207,6 +211,9 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public bool TryAtomicAdd(in TKey key, in TValue value)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
lock (AtomicUpdateLock)
@@ -220,6 +227,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public bool TryAtomicUpdate(in TKey key, in TValue value)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
lock (AtomicUpdateLock)
@@ -233,6 +242,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public bool TryAtomicAddOrUpdate(in TKey key, in TValue valueToAdd, Func<TValue, TValue> valueToUpdateGetter)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
AddOrUpdateResult status;
@@ -276,6 +287,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public void AtomicUpsert(in TKey key, in TValue value)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
lock (AtomicUpdateLock)
{
Upsert(in key, in value);
@@ -284,6 +297,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public void Upsert(in TKey key, in TValue value)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
while (true)
@@ -305,6 +320,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public bool TryDelete(in TKey key)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
if (!ContainsKey(key))
@@ -315,6 +332,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
public void ForceDelete(in TKey key)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
if (key == null)
throw new ArgumentNullException(nameof(key));
while (true)
@@ -6,4 +6,4 @@ public class BTreeIsReadOnlyException : ZoneTreeException
: base("Can't write to read-only BTree.")
{
}
}
}
@@ -0,0 +1,9 @@
namespace Tenray.ZoneTree.Exceptions;
public class ZoneTreeIsReadOnlyException : ZoneTreeException
{
public ZoneTreeIsReadOnlyException()
: base("Can't write to read-only ZoneTree.")
{
}
}
+5
View File
@@ -206,4 +206,9 @@ public interface ITransactionalZoneTree<TKey, TValue> : IDisposable
/// </summary>
/// <param name="key">Key</param>
void DeleteAutoCommit(in TKey key);
/// <summary>
/// Enables read-only mode.
/// </summary>
public bool IsReadOnly { get; set; }
}
+5
View File
@@ -161,4 +161,9 @@ public interface IZoneTree<TKey, TValue> : IDisposable
/// Returns maintenance object belongs to this ZoneTree.
/// </summary>
IZoneTreeMaintenance<TKey, TValue> Maintenance { get; }
/// <summary>
/// Enables read-only mode.
/// </summary>
public bool IsReadOnly { get; set; }
}
@@ -21,6 +21,12 @@ public sealed class OptimisticZoneTree<TKey, TValue> :
public IReadOnlyList<long> UncommittedTransactionIds => TransactionLog.UncommittedTransactionIds;
public bool IsReadOnly
{
get => ZoneTree.IsReadOnly;
set => ZoneTree.IsReadOnly = value;
}
public OptimisticZoneTree(
ZoneTreeOptions<TKey, TValue> options,
ITransactionLog<TKey, TValue> transactionLog,
@@ -381,6 +387,8 @@ public sealed class OptimisticZoneTree<TKey, TValue> :
public void UpsertAutoCommit(in TKey key, in TValue oldVal)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
lock (this)
{
var transactionId = BeginTransaction();
@@ -406,6 +414,8 @@ public sealed class OptimisticZoneTree<TKey, TValue> :
public void DeleteAutoCommit(in TKey key)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
lock (this)
{
var transactionId = BeginTransaction();
@@ -498,6 +508,8 @@ public sealed class OptimisticZoneTree<TKey, TValue> :
public TransactionResult<bool> UpsertNoThrow(long transactionId, in TKey key, in TValue value)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
lock (this)
{
var transaction = GetOrCreateTransactionNoAbortThrow(transactionId);
@@ -528,11 +540,13 @@ public sealed class OptimisticZoneTree<TKey, TValue> :
TransactionLog.AddOrUpdateReadWriteStamp(key, in readWriteStamp);
ZoneTree.Upsert(in key, in value);
return TransactionResult<bool>.Success(!hasOldValue);
}
}
}
public TransactionResult DeleteNoThrow(long transactionId, in TKey key)
{
if (IsReadOnly)
throw new ZoneTreeIsReadOnlyException();
lock (this)
{
var transaction = GetOrCreateTransactionNoAbortThrow(transactionId);