mirror of
https://github.com/ZoneTree/ZoneTree.git
synced 2026-10-28 12:47:01 +08:00
Fixes leaf node split link replacement race condition with neighbours.
This commit is contained in:
@@ -135,11 +135,28 @@ public partial class BTree<TKey, TValue>
|
||||
(var left, var right) = childLeaf
|
||||
.SplitLeaf(pivotPosition, LeafSize, GetNodeLocker(), GetNodeLocker());
|
||||
|
||||
left.Previous = childLeaf.Previous;
|
||||
right.Next = childLeaf.Next;
|
||||
|
||||
var pre = childLeaf.Previous;
|
||||
pre?.WriteLock();
|
||||
// prevent neighbour split at the same time.
|
||||
while (childLeaf.Previous != pre)
|
||||
{
|
||||
pre.WriteUnlock();
|
||||
pre = childLeaf.Previous;
|
||||
pre.WriteLock();
|
||||
}
|
||||
|
||||
var next = childLeaf.Next;
|
||||
next?.WriteLock();
|
||||
// prevent neighbour split at the same time.
|
||||
while (childLeaf.Next != next)
|
||||
{
|
||||
next.WriteUnlock();
|
||||
next = childLeaf.Next;
|
||||
next.WriteLock();
|
||||
}
|
||||
|
||||
left.Previous = pre;
|
||||
right.Next = next;
|
||||
|
||||
if (pre == null)
|
||||
FirstLeafNode = left;
|
||||
@@ -151,6 +168,9 @@ public partial class BTree<TKey, TValue>
|
||||
else
|
||||
next.Previous = right;
|
||||
|
||||
next?.WriteUnlock();
|
||||
pre?.WriteUnlock();
|
||||
|
||||
parent.InsertKeyAndChild(parentInsertPosition, in pivotKey, left, right);
|
||||
}
|
||||
else
|
||||
@@ -176,8 +196,8 @@ public partial class BTree<TKey, TValue>
|
||||
return false;
|
||||
}
|
||||
leaf.Insert(position, in key, in value);
|
||||
node.WriteUnlock();
|
||||
Interlocked.Increment(ref _length);
|
||||
node.WriteUnlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -215,8 +235,8 @@ public partial class BTree<TKey, TValue>
|
||||
|
||||
opIndex = IncrementalIdProvider.NextId();
|
||||
leaf.Insert(position, in key, in value);
|
||||
node.WriteUnlock();
|
||||
Interlocked.Increment(ref _length);
|
||||
node.WriteUnlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -257,8 +277,8 @@ public partial class BTree<TKey, TValue>
|
||||
TValue value = default;
|
||||
adder(ref value);
|
||||
leaf.Insert(position, in key, in value);
|
||||
node.WriteUnlock();
|
||||
Interlocked.Increment(ref _length);
|
||||
node.WriteUnlock();
|
||||
return AddOrUpdateResult.ADDED;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ public sealed class ZoneTree<TKey, TValue> : IZoneTree<TKey, TValue>, IZoneTreeM
|
||||
|
||||
public int ReadOnlySegmentsRecordCount => ReadOnlySegmentQueue.Sum(x => x.Length);
|
||||
|
||||
public int MutableSegmentRecordCount => SegmentZero.Length;
|
||||
|
||||
public int InMemoryRecordCount =>
|
||||
SegmentZero.Length + ReadOnlySegmentsRecordCount;
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ public interface IZoneTreeMaintenance<TKey, TValue>
|
||||
/// </summary>
|
||||
int ReadOnlySegmentsRecordCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the number of records in mutable segment (SegmentZero).
|
||||
/// </summary>
|
||||
int MutableSegmentRecordCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the total number of records that lies in memory
|
||||
/// excluding the sparse array records of DiskSegment.
|
||||
|
||||
Reference in New Issue
Block a user