Fixes leaf node split link replacement race condition with neighbours.

This commit is contained in:
Ahmed Yasin Koculu
2022-08-15 01:27:02 +02:00
parent 2f0f6aa574
commit d8caaf11cb
3 changed files with 33 additions and 6 deletions
@@ -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;
}
+2
View File
@@ -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;
+5
View File
@@ -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.