Compare commits

...

2 commits

Author SHA1 Message Date
bf8298658c started changing to valuetuple 2026-04-28 21:52:24 +02:00
b5b363ae9f Changed some formatting 2026-04-28 21:48:45 +02:00
3 changed files with 29 additions and 25 deletions

View file

@ -10,9 +10,12 @@ namespace PersistentMap
// Public API
// ---------------------------------------------------------
/// <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>
{
// We always get a strategy to avoid branching already here
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
Node<K> current = root;
@ -43,6 +46,7 @@ namespace PersistentMap
{
root = root.EnsureEditable(owner);
// Todo, this should really be made a tuple return value to not stress the GC
var splitResult = InsertRecursive(root, key, value, strategy, owner, out countChanged);
if (splitResult != null)
@ -212,7 +216,7 @@ namespace PersistentMap
where TStrategy : IKeyStrategy<K>
{
if (typeof(K) == typeof(int))
if (typeof(K) == typeof(int))
{
Span<K> keys = node.GetKeys();
ref K firstKeyRef = ref MemoryMarshal.GetReference(keys);
@ -329,11 +333,11 @@ if (typeof(K) == typeof(int))
// Insertion Logic
// ---------------------------------------------------------
private class SplitResult<K>
private class SeplitResult<K>
{
public Node<K> NewNode;
public K Separator;
public SplitResult(Node<K> newNode, K separator)
public SeplitResult(Node<K> newNode, K separator)
{
NewNode = newNode;
Separator = separator;
@ -367,7 +371,7 @@ if (typeof(K) == typeof(int))
leaf.SetCount(count + 1);
}
private static SplitResult<K> SplitLeaf<K, V, TStrategy>(LeafNode<K, V> left, int insertIndex, K key, V value, TStrategy strategy, OwnerId owner)
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>
{
var right = new LeafNode<K, V>(owner, strategy.UsesPrefixes);
@ -391,15 +395,15 @@ if (typeof(K) == typeof(int))
right.SetCount(moveCount);
if (insertIndex < splitPoint || (splitPoint == 0 && insertIndex == 0))
{
{
InsertIntoLeaf(left, insertIndex, key, value, strategy);
}
else
{
}
else
{
InsertIntoLeaf(right, insertIndex - splitPoint, key, value, strategy);
}
}
return new SplitResult<K>(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)
@ -433,7 +437,7 @@ else
node.SetCount(count + 1);
}
private static SplitResult<K> SplitInternal<K, TStrategy>(InternalNode<K> left, int insertIndex, K separator, Node<K> newChild, TStrategy strategy, OwnerId owner)
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>
{
var right = strategy.UsesPrefixes
@ -473,7 +477,7 @@ else
InsertIntoInternal(right, insertIndex - (splitPoint + 1), separator, newChild, strategy);
}
return new SplitResult<K>(right, upKey);
return (right, upKey);
}
// ---------------------------------------------------------

View file

@ -135,7 +135,7 @@ public static class IntScanner
return LinearScanGreater(keys.Slice(i), target) + i;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe int ScanAvx512Greater(ReadOnlySpan<int> keys, int target)
{
var vTarget = Vector512.Create(target);

View file

@ -90,10 +90,10 @@ public abstract class Node<K>
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public PrefixInternalNode<K> AsPrefixInternal()
{
public PrefixInternalNode<K> AsPrefixInternal()
{
return Unsafe.As<PrefixInternalNode<K>>(this);
}
}
}
public sealed class LeafNode<K, V> : Node<K>