surpressed all style warnings from the LSP server.

This commit is contained in:
Linus Björnstam 2026-05-21 13:13:22 +02:00
parent 7ee2238248
commit 23c4ac299e
13 changed files with 346 additions and 371 deletions

View file

@ -11,20 +11,20 @@ namespace PersistentOrderedMap
/// <summary>TryGetValue tries to get the value at mapping key. If it finds the key it sets th
/// out var to value and returns true. </summary>
public static bool TryGetValue<K, V, TStrategy>(Node<K> root, K key, TStrategy strategy, out V value)
where TStrategy : IKeyStrategy<K>
public static bool TryGetValue<TK, TV, TStrategy>(Node<TK> root, TK key, TStrategy strategy, out TV value)
where TStrategy : IKeyStrategy<TK>
{
// We always get a strategy to avoid branching already here
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
Node<K> current = root;
Node<TK> current = root;
while (true)
{
if (current.IsLeaf)
{
var leaf = current.AsLeaf<V>();
var leaf = current.AsLeaf<TV>();
int index = FindIndex(leaf, key, keyPrefix, strategy);
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys[index], key) == 0)
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys![index], key) == 0)
{
value = leaf.Values[index];
return true;
@ -41,8 +41,8 @@ namespace PersistentOrderedMap
}
}
public static Node<K> Set<K, V, TStrategy>(Node<K> root, K key, V value, TStrategy strategy, OwnerId owner, out bool countChanged)
where TStrategy : IKeyStrategy<K>
public static Node<TK> Set<TK, TV, TStrategy>(Node<TK> root, TK key, TV value, TStrategy strategy, OwnerId owner, out bool countChanged)
where TStrategy : IKeyStrategy<TK>
{
root = root.EnsureEditable(owner);
@ -52,8 +52,8 @@ namespace PersistentOrderedMap
if (newNode != null)
{
var newRoot = strategy.UsesPrefixes
? new PrefixInternalNode<K>(owner)
: new InternalNode<K>(owner);
? new PrefixInternalNode<TK>(owner)
: new InternalNode<TK>(owner);
newRoot.Keys[0] = sep;
newRoot.Children[0] = root;
@ -71,27 +71,27 @@ namespace PersistentOrderedMap
return root;
}
private static (Node<K>? newNode, K separator ) InsertRecursive<K, V>(Node<K> node, K key, V value, IKeyStrategy<K> strategy, OwnerId owner, out bool added)
private static (Node<TK>? newNode, TK separator ) InsertRecursive<TK, TV>(Node<TK> node, TK key, TV value, IKeyStrategy<TK> strategy, OwnerId owner, out bool added)
{
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
if (node.IsLeaf)
{
var leaf = node.AsLeaf<V>();
var leaf = node.AsLeaf<TV>();
int index = FindIndex(leaf, key, keyPrefix, strategy);
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys[index], key) == 0)
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys![index], key) == 0)
{
leaf.Values[index] = value;
added = false;
return (null, default);
return (null, default)!;
}
added = true;
if (leaf.Header.Count < LeafNode<K, V>.Capacity)
if (leaf.Header.Count < LeafNode<TK, TV>.Capacity)
{
InsertIntoLeaf(leaf, index, key, value, strategy);
return (null, default);
return (null, default)!;
}
else
{
@ -110,26 +110,25 @@ namespace PersistentOrderedMap
if (newNode != null)
{
if (internalNode.Header.Count < InternalNode<K>.Capacity - 1)
if (internalNode.Header.Count < InternalNode<TK>.Capacity - 1)
{
InsertIntoInternal(internalNode, index, sep, newNode, strategy);
return (null, default);
}
else
{
return SplitInternal(internalNode, index, sep, newNode, strategy, owner);
return (null, default)!;
}
return SplitInternal(internalNode, index, sep, newNode, strategy, owner);
}
return (null, default);
return (null, default)!;
}
}
public static Node<K> Remove<K, V, TStrategy>(Node<K> root, K key, TStrategy strategy, OwnerId owner, out bool countChanged)
where TStrategy : IKeyStrategy<K>
public static Node<TK> Remove<TK, TV, TStrategy>(Node<TK> root, TK key, TStrategy strategy, OwnerId owner, out bool countChanged)
where TStrategy : IKeyStrategy<TK>
{
root = root.EnsureEditable(owner);
bool rebalanceNeeded = RemoveRecursive<K, V, TStrategy>(root, key, strategy, owner, out countChanged);
bool rebalanceNeeded = RemoveRecursive<TK, TV, TStrategy>(root, key, strategy, owner, out countChanged);
if (rebalanceNeeded)
{
@ -146,21 +145,21 @@ namespace PersistentOrderedMap
return root;
}
private static bool RemoveRecursive<K, V, TStrategy>(Node<K> node, K key, TStrategy strategy, OwnerId owner, out bool removed)
where TStrategy : IKeyStrategy<K>
private static bool RemoveRecursive<TK, TV, TStrategy>(Node<TK> node, TK key, TStrategy strategy, OwnerId owner, out bool removed)
where TStrategy : IKeyStrategy<TK>
{
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
if (node.IsLeaf)
{
var leaf = node.AsLeaf<V>();
var leaf = node.AsLeaf<TV>();
int index = FindIndex(leaf, key, keyPrefix, strategy);
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys[index], key) == 0)
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys![index], key) == 0)
{
RemoveFromLeaf(leaf, index, strategy);
removed = true;
return leaf.Header.Count < LeafNode<K, V>.MergeThreshold;
return leaf.Header.Count < LeafNode<TK, TV>.MergeThreshold;
}
removed = false;
@ -174,11 +173,11 @@ namespace PersistentOrderedMap
var child = internalNode.Children[index]!.EnsureEditable(owner);
internalNode.Children[index] = child;
bool childUnderflow = RemoveRecursive<K, V, TStrategy>(child, key, strategy, owner, out removed);
bool childUnderflow = RemoveRecursive<TK, TV, TStrategy>(child, key, strategy, owner, out removed);
if (removed && childUnderflow)
{
return HandleUnderflow<K, V, TStrategy>(internalNode, index, strategy, owner);
return HandleUnderflow<TK, TV, TStrategy>(internalNode, index, strategy, owner);
}
return false;
}
@ -189,16 +188,16 @@ namespace PersistentOrderedMap
// ---------------------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int FindIndex<K,V, TStrategy>(LeafNode<K,V> node, K key, long keyPrefix, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
internal static int FindIndex<TK,TV, TStrategy>(LeafNode<TK,TV> node, TK key, long keyPrefix, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
if (typeof(K) == typeof(int))
if (typeof(TK) == typeof(int))
{
Span<K> keys = node.GetKeys();
ref K firstKeyRef = ref MemoryMarshal.GetReference(keys);
ref int firstIntRef = ref Unsafe.As<K, int>(ref firstKeyRef);
Span<TK> keys = node.GetKeys();
ref TK firstKeyRef = ref MemoryMarshal.GetReference(keys);
ref int firstIntRef = ref Unsafe.As<TK, int>(ref firstKeyRef);
ReadOnlySpan<int> intKeys = MemoryMarshal.CreateReadOnlySpan(ref firstIntRef, keys.Length);
int intKey = Unsafe.As<K, int>(ref key);
int intKey = Unsafe.As<TK, int>(ref key);
return IntScanner.FindFirstGreaterOrEqual(intKeys, intKey);
}
@ -212,17 +211,17 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int FindRoutingIndex<K, TStrategy>(InternalNode<K> node, K key, long keyPrefix, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
internal static int FindRoutingIndex<TK, TStrategy>(InternalNode<TK> node, TK key, long keyPrefix, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
if (typeof(K) == typeof(int))
if (typeof(TK) == typeof(int))
{
Span<K> keys = node.GetKeys();
ref K firstKeyRef = ref MemoryMarshal.GetReference(keys);
ref int firstIntRef = ref Unsafe.As<K, int>(ref firstKeyRef);
Span<TK> keys = node.GetKeys();
ref TK firstKeyRef = ref MemoryMarshal.GetReference(keys);
ref int firstIntRef = ref Unsafe.As<TK, int>(ref firstKeyRef);
ReadOnlySpan<int> intKeys = MemoryMarshal.CreateReadOnlySpan(ref firstIntRef, keys.Length);
int intKey = Unsafe.As<K, int>(ref key);
int intKey = Unsafe.As<TK, int>(ref key);
return IntScanner.FindFirstGreater(intKeys, intKey);
}
if (!strategy.UsesPrefixes)
@ -235,8 +234,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int RefineSearch<K, TStrategy>(int startIndex, ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int RefineSearch<TK, TStrategy>(int startIndex, ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int i = startIndex;
while (i < keys.Length && strategy.Compare(keys[i], key) < 0) i++;
@ -244,8 +243,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int RefineRouting<K, TStrategy>(int startIndex, ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int RefineRouting<TK, TStrategy>(int startIndex, ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int i = startIndex;
while (i < keys.Length && strategy.Compare(keys[i], key) <= 0) i++;
@ -253,8 +252,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int FallbackSearchKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int FallbackSearchKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
return strategy.UseBinarySearch
? BinarySearchKeys(keys, key, strategy)
@ -262,8 +261,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int FallbackRoutingKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int FallbackRoutingKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
return strategy.UseBinarySearch
? BinaryRoutingKeys(keys, key, strategy)
@ -271,8 +270,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LinearSearchKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int LinearSearchKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int i = 0;
while (i < keys.Length && strategy.Compare(keys[i], key) < 0) i++;
@ -280,8 +279,8 @@ namespace PersistentOrderedMap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LinearRoutingKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int LinearRoutingKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int i = 0;
while (i < keys.Length && strategy.Compare(keys[i], key) <= 0) i++;
@ -290,17 +289,17 @@ namespace PersistentOrderedMap
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int BinarySearchKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int BinarySearchKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int low = 0;
int high = keys.Length - 1;
ref K keysRef = ref MemoryMarshal.GetReference(keys);
ref TK keysRef = ref MemoryMarshal.GetReference(keys);
while (low <= high)
{
int mid = low + ((high - low) >> 1);
K midKey = Unsafe.Add(ref keysRef, mid);
TK midKey = Unsafe.Add(ref keysRef, mid);
int cmp = strategy.Compare(midKey, key);
if (cmp == 0) return mid;
@ -310,17 +309,17 @@ namespace PersistentOrderedMap
return low;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int BinaryRoutingKeys<K, TStrategy>(ReadOnlySpan<K> keys, K key, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static int BinaryRoutingKeys<TK, TStrategy>(ReadOnlySpan<TK> keys, TK key, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int low = 0;
int high = keys.Length - 1;
ref K keysRef = ref MemoryMarshal.GetReference(keys);
ref TK keysRef = ref MemoryMarshal.GetReference(keys);
while (low <= high)
{
int mid = low + ((high - low) >> 1);
K midKey = Unsafe.Add(ref keysRef, mid);
TK midKey = Unsafe.Add(ref keysRef, mid);
int cmp = strategy.Compare(midKey, key);
if (cmp <= 0) low = mid + 1;
@ -333,19 +332,8 @@ namespace PersistentOrderedMap
// Insertion Logic
// ---------------------------------------------------------
private class SeplitResult<K>
{
public Node<K> NewNode;
public K Separator;
public SeplitResult(Node<K> newNode, K separator)
{
NewNode = newNode;
Separator = separator;
}
}
private static void InsertIntoLeaf<K, V, TStrategy>(LeafNode<K, V> leaf, int index, K key, V value, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void InsertIntoLeaf<TK, TV, TStrategy>(LeafNode<TK, TV> leaf, int index, TK key, TV value, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int count = leaf.Header.Count;
if (index < count)
@ -360,7 +348,7 @@ namespace PersistentOrderedMap
}
}
leaf.Keys[index] = key;
leaf.Keys![index] = key;
leaf.Values[index] = value;
if (strategy.UsesPrefixes)
@ -371,10 +359,10 @@ namespace PersistentOrderedMap
leaf.SetCount(count + 1);
}
private static (Node<K>, K) SplitLeaf<K, V, TStrategy>(LeafNode<K, V> left, int insertIndex, K key, V value, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<K>
private static (Node<TK>, TK) SplitLeaf<TK, TV, TStrategy>(LeafNode<TK, TV> left, int insertIndex, TK key, TV value, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<TK>
{
var right = new LeafNode<K, V>(owner, strategy.UsesPrefixes);
var right = new LeafNode<TK, TV>(owner, strategy.UsesPrefixes);
int totalCount = left.Header.Count;
int splitPoint = (insertIndex == totalCount) ? totalCount : (insertIndex == 0 ? 0 : totalCount / 2);
@ -403,21 +391,21 @@ namespace PersistentOrderedMap
InsertIntoLeaf(right, insertIndex - splitPoint, key, value, strategy);
}
return (right, right.Keys[0]);
return (right, right.Keys![0]);
}
private static void InsertIntoInternal<K, TStrategy>(InternalNode<K> node, int index, K separator, Node<K> newChild, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void InsertIntoInternal<TK, TStrategy>(InternalNode<TK> node, int index, TK separator, Node<TK> newChild, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int count = node.Header.Count;
if (index < count)
{
int moveCount = count - index;
Span<K> keysSpan = node.Keys;
Span<TK> keysSpan = node.Keys;
keysSpan.Slice(index, moveCount).CopyTo(keysSpan.Slice(index + 1));
Span<Node<K>> childrenSpan = node.Children;
Span<Node<TK>> childrenSpan = node.Children!;
childrenSpan.Slice(index + 1, moveCount).CopyTo(childrenSpan.Slice(index + 2));
if (strategy.UsesPrefixes)
@ -437,26 +425,26 @@ namespace PersistentOrderedMap
node.SetCount(count + 1);
}
private static (Node<K>, K) SplitInternal<K, TStrategy>(InternalNode<K> left, int insertIndex, K separator, Node<K> newChild, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<K>
private static (Node<TK>, TK) SplitInternal<TK, TStrategy>(InternalNode<TK> left, int insertIndex, TK separator, Node<TK> newChild, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<TK>
{
var right = strategy.UsesPrefixes
? new PrefixInternalNode<K>(owner)
: new InternalNode<K>(owner);
? new PrefixInternalNode<TK>(owner)
: new InternalNode<TK>(owner);
int count = left.Header.Count;
int splitPoint = count / 2;
K upKey = left.Keys[splitPoint];
TK upKey = left.Keys[splitPoint];
int moveCount = count - splitPoint - 1;
if (moveCount > 0)
{
Span<K> leftKeys = left.Keys;
Span<K> rightKeys = right.Keys;
Span<TK> leftKeys = left.Keys;
Span<TK> rightKeys = right.Keys;
leftKeys.Slice(splitPoint + 1, moveCount).CopyTo(rightKeys);
Span<Node<K>> leftChildren = left.Children;
Span<Node<K>> rightChildren = right.Children;
Span<Node<TK>> leftChildren = left.Children!;
Span<Node<TK>> rightChildren = right.Children!;
leftChildren.Slice(splitPoint + 1, moveCount + 1).CopyTo(rightChildren);
if (strategy.UsesPrefixes)
@ -484,8 +472,8 @@ namespace PersistentOrderedMap
// Removal Logic
// ---------------------------------------------------------
private static void RemoveFromLeaf<K, V, TStrategy>(LeafNode<K, V> leaf, int index, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void RemoveFromLeaf<TK, TV, TStrategy>(LeafNode<TK, TV> leaf, int index, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
int count = leaf.Header.Count;
int moveCount = count - index - 1;
@ -504,8 +492,8 @@ namespace PersistentOrderedMap
leaf.SetCount(count - 1);
}
private static bool HandleUnderflow<K, V, TStrategy>(InternalNode<K> parent, int childIndex, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<K>
private static bool HandleUnderflow<TK, TV, TStrategy>(InternalNode<TK> parent, int childIndex, TStrategy strategy, OwnerId owner)
where TStrategy : IKeyStrategy<TK>
{
if (childIndex < parent.Header.Count)
{
@ -515,13 +503,13 @@ namespace PersistentOrderedMap
if (CanBorrow(rightSibling))
{
RotateLeft<K, V, TStrategy>(parent, childIndex, leftChild, rightSibling, strategy);
RotateLeft<TK, TV, TStrategy>(parent, childIndex, leftChild, rightSibling, strategy);
return false;
}
else
{
Merge<K, V, TStrategy>(parent, childIndex, leftChild, rightSibling, strategy);
return parent.Header.Count < LeafNode<K, V>.MergeThreshold;
Merge<TK, TV, TStrategy>(parent, childIndex, leftChild, rightSibling, strategy);
return parent.Header.Count < LeafNode<TK, TV>.MergeThreshold;
}
}
else if (childIndex > 0)
@ -532,31 +520,31 @@ namespace PersistentOrderedMap
if (CanBorrow(leftSibling))
{
RotateRight<K, V, TStrategy>(parent, childIndex - 1, leftSibling, rightChild, strategy);
RotateRight<TK, TV, TStrategy>(parent, childIndex - 1, leftSibling, rightChild, strategy);
return false;
}
else
{
Merge<K, V, TStrategy>(parent, childIndex - 1, leftSibling, rightChild, strategy);
return parent.Header.Count < LeafNode<K, V>.MergeThreshold;
Merge<TK, TV, TStrategy>(parent, childIndex - 1, leftSibling, rightChild, strategy);
return parent.Header.Count < LeafNode<TK, TV>.MergeThreshold;
}
}
return true;
}
private static bool CanBorrow<K>(Node<K> node)
private static bool CanBorrow<TK>(Node<TK> node)
{
return node.Header.Count > 8 + 1;
}
private static void Merge<K, V, TStrategy>(InternalNode<K> parent, int separatorIndex, Node<K> left, Node<K> right, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void Merge<TK, TV, TStrategy>(InternalNode<TK> parent, int separatorIndex, Node<TK> left, Node<TK> right, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
if (left.IsLeaf)
{
var leftLeaf = left.AsLeaf<V>();
var rightLeaf = right.AsLeaf<V>();
var leftLeaf = left.AsLeaf<TV>();
var rightLeaf = right.AsLeaf<TV>();
int lCount = leftLeaf.Header.Count;
int rCount = rightLeaf.Header.Count;
@ -576,7 +564,7 @@ namespace PersistentOrderedMap
var leftInternal = left.AsInternal();
var rightInternal = right.AsInternal();
K separator = parent.Keys[separatorIndex];
TK separator = parent.Keys[separatorIndex];
int lCount = leftInternal.Header.Count;
leftInternal.Keys[lCount] = separator;
@ -587,8 +575,8 @@ namespace PersistentOrderedMap
}
int rCount = rightInternal.Header.Count;
Span<K> rightKeys = rightInternal.Keys;
Span<K> leftKeys = leftInternal.Keys;
Span<TK> rightKeys = rightInternal.Keys;
Span<TK> leftKeys = leftInternal.Keys;
rightKeys.Slice(0, rCount).CopyTo(leftKeys.Slice(lCount + 1));
if (strategy.UsesPrefixes)
@ -596,8 +584,8 @@ namespace PersistentOrderedMap
rightInternal.AllPrefixes.Slice(0, rCount).CopyTo(leftInternal.AllPrefixes.Slice(lCount + 1));
}
Span<Node<K>> rightChildren = rightInternal.Children;
Span<Node<K>> leftChildren = leftInternal.Children;
Span<Node<TK>> rightChildren = rightInternal.Children!;
Span<Node<TK>> leftChildren = leftInternal.Children!;
rightChildren.Slice(0, rCount + 1).CopyTo(leftChildren.Slice(lCount + 1));
leftInternal.SetCount(lCount + 1 + rCount);
@ -608,7 +596,7 @@ namespace PersistentOrderedMap
if (moveCount > 0)
{
Span<K> parentKeys = parent.Keys;
Span<TK> parentKeys = parent.Keys;
parentKeys.Slice(separatorIndex + 1, moveCount).CopyTo(parentKeys.Slice(separatorIndex));
if (strategy.UsesPrefixes)
@ -616,22 +604,22 @@ namespace PersistentOrderedMap
parent.AllPrefixes.Slice(separatorIndex + 1, moveCount).CopyTo(parent.AllPrefixes.Slice(separatorIndex));
}
Span<Node<K>> parentChildren = parent.Children;
Span<Node<TK>> parentChildren = parent.Children!;
parentChildren.Slice(separatorIndex + 2, moveCount).CopyTo(parentChildren.Slice(separatorIndex + 1));
}
parent.SetCount(pCount - 1);
}
private static void RotateLeft<K, V, TStrategy>(InternalNode<K> parent, int separatorIndex, Node<K> left, Node<K> right, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void RotateLeft<TK, TV, TStrategy>(InternalNode<TK> parent, int separatorIndex, Node<TK> left, Node<TK> right, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
if (left.IsLeaf)
{
var leftLeaf = left.AsLeaf<V>();
var rightLeaf = right.AsLeaf<V>();
var leftLeaf = left.AsLeaf<TV>();
var rightLeaf = right.AsLeaf<TV>();
InsertIntoLeaf(leftLeaf, leftLeaf.Header.Count, rightLeaf.Keys[0], rightLeaf.Values[0], strategy);
InsertIntoLeaf(leftLeaf, leftLeaf.Header.Count, rightLeaf.Keys![0], rightLeaf.Values[0], strategy);
RemoveFromLeaf(rightLeaf, 0, strategy);
parent.Keys[separatorIndex] = rightLeaf.Keys[0];
@ -645,7 +633,7 @@ namespace PersistentOrderedMap
var leftInternal = left.AsInternal();
var rightInternal = right.AsInternal();
K sep = parent.Keys[separatorIndex];
TK sep = parent.Keys[separatorIndex];
InsertIntoInternal(leftInternal, leftInternal.Header.Count, sep, rightInternal.Children[0]!, strategy);
parent.Keys[separatorIndex] = rightInternal.Keys[0];
@ -656,12 +644,12 @@ namespace PersistentOrderedMap
int rCount = rightInternal.Header.Count;
Span<Node<K>> rightChildren = rightInternal.Children;
Span<Node<TK>> rightChildren = rightInternal.Children!;
rightChildren.Slice(1, rCount).CopyTo(rightChildren);
if (rCount > 1)
{
Span<K> rightKeys = rightInternal.Keys;
Span<TK> rightKeys = rightInternal.Keys;
rightKeys.Slice(1, rCount - 1).CopyTo(rightKeys);
if (strategy.UsesPrefixes)
@ -674,19 +662,19 @@ namespace PersistentOrderedMap
}
}
private static void RotateRight<K, V, TStrategy>(InternalNode<K> parent, int separatorIndex, Node<K> left, Node<K> right, TStrategy strategy)
where TStrategy : IKeyStrategy<K>
private static void RotateRight<TK, TV, TStrategy>(InternalNode<TK> parent, int separatorIndex, Node<TK> left, Node<TK> right, TStrategy strategy)
where TStrategy : IKeyStrategy<TK>
{
if (left.IsLeaf)
{
var leftLeaf = left.AsLeaf<V>();
var rightLeaf = right.AsLeaf<V>();
var leftLeaf = left.AsLeaf<TV>();
var rightLeaf = right.AsLeaf<TV>();
int last = leftLeaf.Header.Count - 1;
InsertIntoLeaf(rightLeaf, 0, leftLeaf.Keys[last], leftLeaf.Values[last], strategy);
InsertIntoLeaf(rightLeaf, 0, leftLeaf.Keys![last], leftLeaf.Values[last], strategy);
RemoveFromLeaf(leftLeaf, last, strategy);
parent.Keys[separatorIndex] = rightLeaf.Keys[0];
parent.Keys[separatorIndex] = rightLeaf.Keys![0];
if (strategy.UsesPrefixes)
{
parent.AllPrefixes[separatorIndex] = strategy.GetPrefix(rightLeaf.Keys[0]);
@ -698,7 +686,7 @@ namespace PersistentOrderedMap
var rightInternal = right.AsInternal();
int last = leftInternal.Header.Count - 1;
K sep = parent.Keys[separatorIndex];
TK sep = parent.Keys[separatorIndex];
InsertIntoInternal(rightInternal, 0, sep, leftInternal.Children[last + 1]!, strategy);
parent.Keys[separatorIndex] = leftInternal.Keys[last];
@ -711,7 +699,7 @@ namespace PersistentOrderedMap
}
}
public static bool TryGetMin<K, V>(Node<K> root, out K key, out V value)
public static bool TryGetMin<TK, TV>(Node<TK> root, out TK key, out TV value)
{
var current = root;
while (!current.IsLeaf)
@ -719,7 +707,7 @@ namespace PersistentOrderedMap
current = current.AsInternal().Children[0]!;
}
var leaf = current.AsLeaf<V>();
var leaf = current.AsLeaf<TV>();
if (leaf.Header.Count == 0)
{
key = default!;
@ -727,12 +715,12 @@ namespace PersistentOrderedMap
return false;
}
key = leaf.Keys[0];
key = leaf.Keys![0];
value = leaf.Values[0];
return true;
}
public static bool TryGetMax<K, V>(Node<K> root, out K key, out V value)
public static bool TryGetMax<TK, TV>(Node<TK> root, out TK key, out TV value)
{
var current = root;
while (!current.IsLeaf)
@ -741,7 +729,7 @@ namespace PersistentOrderedMap
current = internalNode.Children[internalNode.Header.Count]!;
}
var leaf = current.AsLeaf<V>();
var leaf = current.AsLeaf<TV>();
if (leaf.Header.Count == 0)
{
key = default!;
@ -750,15 +738,15 @@ namespace PersistentOrderedMap
}
int last = leaf.Header.Count - 1;
key = leaf.Keys[last];
key = leaf.Keys![last];
value = leaf.Values[last];
return true;
}
public static bool TryGetSuccessor<K, V, TStrategy>(Node<K> root, K key, TStrategy strategy, out K nextKey, out V nextValue)
where TStrategy : IKeyStrategy<K>
public static bool TryGetSuccessor<TK, TV, TStrategy>(Node<TK> root, TK key, TStrategy strategy, out TK nextKey, out TV nextValue)
where TStrategy : IKeyStrategy<TK>
{
InternalNode<K>[] path = new InternalNode<K>[32];
InternalNode<TK>[] path = new InternalNode<TK>[32];
int[] indices = new int[32];
int depth = 0;
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
@ -774,14 +762,14 @@ namespace PersistentOrderedMap
current = internalNode.Children[idx]!;
}
var leaf = current.AsLeaf<V>();
var leaf = current.AsLeaf<TV>();
int index = FindIndex(leaf, key, keyPrefix, strategy);
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys[index], key) == 0) index++;
if (index < leaf.Header.Count && strategy.Compare(leaf.Keys![index], key) == 0) index++;
if (index < leaf.Header.Count)
{
nextKey = leaf.Keys[index];
nextKey = leaf.Keys![index];
nextValue = leaf.Values[index];
return true;
}
@ -796,8 +784,8 @@ namespace PersistentOrderedMap
current = current.AsInternal().Children[0]!;
}
var targetLeaf = current.AsLeaf<V>();
nextKey = targetLeaf.Keys[0];
var targetLeaf = current.AsLeaf<TV>();
nextKey = targetLeaf.Keys![0];
nextValue = targetLeaf.Values[0];
return true;
}
@ -808,10 +796,10 @@ namespace PersistentOrderedMap
return false;
}
public static bool TryGetPredecessor<K, V, TStrategy>(Node<K> root, K key, TStrategy strategy, out K prevKey, out V prevValue)
where TStrategy : IKeyStrategy<K>
public static bool TryGetPredecessor<TK, TV, TStrategy>(Node<TK> root, TK key, TStrategy strategy, out TK prevKey, out TV prevValue)
where TStrategy : IKeyStrategy<TK>
{
InternalNode<K>[] path = new InternalNode<K>[32];
InternalNode<TK>[] path = new InternalNode<TK>[32];
int[] indices = new int[32];
int depth = 0;
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
@ -827,12 +815,12 @@ namespace PersistentOrderedMap
current = internalNode.Children[idx]!;
}
var leaf = current.AsLeaf<V>();
var leaf = current.AsLeaf<TV>();
int index = FindIndex(leaf, key, keyPrefix, strategy);
if (index > 0)
{
prevKey = leaf.Keys[index - 1];
prevKey = leaf.Keys![index - 1];
prevValue = leaf.Values[index - 1];
return true;
}
@ -848,9 +836,9 @@ namespace PersistentOrderedMap
current = internalNode.Children[internalNode.Header.Count]!;
}
var targetLeaf = current.AsLeaf<V>();
var targetLeaf = current.AsLeaf<TV>();
int last = targetLeaf.Header.Count - 1;
prevKey = targetLeaf.Keys[last];
prevKey = targetLeaf.Keys![last];
prevValue = targetLeaf.Values[last];
return true;
}