Compare commits
No commits in common. "bf8298658cffd14038547824ea8ed3bd09b3be2d" and "a6e8ced7f7402c43e3bf79881ab7392b58176619" have entirely different histories.
bf8298658c
...
a6e8ced7f7
3 changed files with 25 additions and 29 deletions
|
|
@ -10,12 +10,9 @@ namespace PersistentMap
|
||||||
// Public API
|
// 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)
|
public static bool TryGetValue<K, V, TStrategy>(Node<K> root, K key, TStrategy strategy, out V value)
|
||||||
where TStrategy : IKeyStrategy<K>
|
where TStrategy : IKeyStrategy<K>
|
||||||
{
|
{
|
||||||
// We always get a strategy to avoid branching already here
|
|
||||||
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
|
long keyPrefix = strategy.UsesPrefixes ? strategy.GetPrefix(key) : 0;
|
||||||
|
|
||||||
Node<K> current = root;
|
Node<K> current = root;
|
||||||
|
|
@ -46,7 +43,6 @@ namespace PersistentMap
|
||||||
{
|
{
|
||||||
root = root.EnsureEditable(owner);
|
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);
|
var splitResult = InsertRecursive(root, key, value, strategy, owner, out countChanged);
|
||||||
|
|
||||||
if (splitResult != null)
|
if (splitResult != null)
|
||||||
|
|
@ -216,7 +212,7 @@ namespace PersistentMap
|
||||||
where TStrategy : IKeyStrategy<K>
|
where TStrategy : IKeyStrategy<K>
|
||||||
{
|
{
|
||||||
|
|
||||||
if (typeof(K) == typeof(int))
|
if (typeof(K) == typeof(int))
|
||||||
{
|
{
|
||||||
Span<K> keys = node.GetKeys();
|
Span<K> keys = node.GetKeys();
|
||||||
ref K firstKeyRef = ref MemoryMarshal.GetReference(keys);
|
ref K firstKeyRef = ref MemoryMarshal.GetReference(keys);
|
||||||
|
|
@ -333,11 +329,11 @@ namespace PersistentMap
|
||||||
// Insertion Logic
|
// Insertion Logic
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
private class SeplitResult<K>
|
private class SplitResult<K>
|
||||||
{
|
{
|
||||||
public Node<K> NewNode;
|
public Node<K> NewNode;
|
||||||
public K Separator;
|
public K Separator;
|
||||||
public SeplitResult(Node<K> newNode, K separator)
|
public SplitResult(Node<K> newNode, K separator)
|
||||||
{
|
{
|
||||||
NewNode = newNode;
|
NewNode = newNode;
|
||||||
Separator = separator;
|
Separator = separator;
|
||||||
|
|
@ -371,7 +367,7 @@ namespace PersistentMap
|
||||||
leaf.SetCount(count + 1);
|
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)
|
private static SplitResult<K> SplitLeaf<K, V, TStrategy>(LeafNode<K, V> left, int insertIndex, K key, V value, TStrategy strategy, OwnerId owner)
|
||||||
where TStrategy : IKeyStrategy<K>
|
where TStrategy : IKeyStrategy<K>
|
||||||
{
|
{
|
||||||
var right = new LeafNode<K, V>(owner, strategy.UsesPrefixes);
|
var right = new LeafNode<K, V>(owner, strategy.UsesPrefixes);
|
||||||
|
|
@ -395,15 +391,15 @@ namespace PersistentMap
|
||||||
right.SetCount(moveCount);
|
right.SetCount(moveCount);
|
||||||
|
|
||||||
if (insertIndex < splitPoint || (splitPoint == 0 && insertIndex == 0))
|
if (insertIndex < splitPoint || (splitPoint == 0 && insertIndex == 0))
|
||||||
{
|
{
|
||||||
InsertIntoLeaf(left, insertIndex, key, value, strategy);
|
InsertIntoLeaf(left, insertIndex, key, value, strategy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InsertIntoLeaf(right, insertIndex - splitPoint, key, value, strategy);
|
InsertIntoLeaf(right, insertIndex - splitPoint, key, value, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (right, right.Keys[0]);
|
return new SplitResult<K>(right, right.Keys[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InsertIntoInternal<K, TStrategy>(InternalNode<K> node, int index, K separator, Node<K> newChild, TStrategy strategy)
|
private static void InsertIntoInternal<K, TStrategy>(InternalNode<K> node, int index, K separator, Node<K> newChild, TStrategy strategy)
|
||||||
|
|
@ -437,7 +433,7 @@ namespace PersistentMap
|
||||||
node.SetCount(count + 1);
|
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)
|
private static SplitResult<K> SplitInternal<K, TStrategy>(InternalNode<K> left, int insertIndex, K separator, Node<K> newChild, TStrategy strategy, OwnerId owner)
|
||||||
where TStrategy : IKeyStrategy<K>
|
where TStrategy : IKeyStrategy<K>
|
||||||
{
|
{
|
||||||
var right = strategy.UsesPrefixes
|
var right = strategy.UsesPrefixes
|
||||||
|
|
@ -477,7 +473,7 @@ namespace PersistentMap
|
||||||
InsertIntoInternal(right, insertIndex - (splitPoint + 1), separator, newChild, strategy);
|
InsertIntoInternal(right, insertIndex - (splitPoint + 1), separator, newChild, strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (right, upKey);
|
return new SplitResult<K>(right, upKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ public static class IntScanner
|
||||||
return LinearScanGreater(keys.Slice(i), target) + i;
|
return LinearScanGreater(keys.Slice(i), target) + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static unsafe int ScanAvx512Greater(ReadOnlySpan<int> keys, int target)
|
private static unsafe int ScanAvx512Greater(ReadOnlySpan<int> keys, int target)
|
||||||
{
|
{
|
||||||
var vTarget = Vector512.Create(target);
|
var vTarget = Vector512.Create(target);
|
||||||
|
|
|
||||||
|
|
@ -90,10 +90,10 @@ public abstract class Node<K>
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public PrefixInternalNode<K> AsPrefixInternal()
|
public PrefixInternalNode<K> AsPrefixInternal()
|
||||||
{
|
{
|
||||||
return Unsafe.As<PrefixInternalNode<K>>(this);
|
return Unsafe.As<PrefixInternalNode<K>>(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class LeafNode<K, V> : Node<K>
|
public sealed class LeafNode<K, V> : Node<K>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue