mirror of
https://github.com/ZoneTree/ZoneTree.git
synced 2026-10-19 23:30:15 +08:00
Adds read-only mode.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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.")
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user