2026-02-01 20:52:23 +01:00
|
|
|
using System.Collections;
|
|
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
namespace PersistentOrderedMap;
|
2026-02-01 20:52:23 +01:00
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
public sealed class PersistentOrderedMap<K, V, TStrategy> : BaseOrderedMap<K, V, TStrategy>, IEnumerable, IEnumerable<KeyValuePair<K, V>> where TStrategy : IKeyStrategy<K>
|
2026-02-01 20:52:23 +01:00
|
|
|
{
|
2026-05-07 07:44:55 +02:00
|
|
|
internal PersistentOrderedMap(Node<K> root, TStrategy strategy, int count)
|
2026-02-01 20:52:23 +01:00
|
|
|
: base(root, strategy, count) { }
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
|
// Immutable Write API (Returns new Map)
|
|
|
|
|
// ---------------------------------------------------------
|
2026-05-07 07:44:55 +02:00
|
|
|
public PersistentOrderedMap<K, V, TStrategy> Set(K key, V value)
|
2026-02-01 20:52:23 +01:00
|
|
|
{
|
|
|
|
|
// OPTIMIZATION: Use OwnerId.None (0).
|
|
|
|
|
// This signals EnsureEditable to always copy the root path,
|
|
|
|
|
// producing a new tree of nodes that also have OwnerId.None.
|
2026-02-11 12:56:48 +01:00
|
|
|
var newRoot = BTreeFunctions.Set(_root, key, value, _strategy, OwnerId.None, out bool countChanged);
|
2026-05-07 07:44:55 +02:00
|
|
|
return new PersistentOrderedMap<K, V, TStrategy>(newRoot, _strategy, countChanged ? Count + 1 : Count);
|
2026-02-01 20:52:23 +01:00
|
|
|
}
|
|
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
public static PersistentOrderedMap<K, V, TStrategy> Empty(TStrategy strategy)
|
2026-02-01 20:52:23 +01:00
|
|
|
{
|
|
|
|
|
// Create an empty Leaf Node.
|
|
|
|
|
// 'default(OwnerId)' (usually 0) marks this node as Immutable/Persistent.
|
|
|
|
|
// This ensures that any subsequent Set/Remove will clone this node
|
|
|
|
|
// instead of modifying it in place.
|
2026-04-22 15:55:33 +02:00
|
|
|
var emptyRoot = new LeafNode<K, V>(default(OwnerId), strategy.UsesPrefixes);
|
2026-02-01 20:52:23 +01:00
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
return new PersistentOrderedMap<K, V, TStrategy>(emptyRoot, strategy, 0);
|
2026-02-01 20:52:23 +01:00
|
|
|
}
|
|
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
public PersistentOrderedMap<K, V, TStrategy> Remove(K key)
|
2026-02-01 20:52:23 +01:00
|
|
|
{
|
2026-02-11 12:56:48 +01:00
|
|
|
var newRoot = BTreeFunctions.Remove<K,V, TStrategy>(_root, key, _strategy, OwnerId.None, out bool removed);
|
|
|
|
|
if (!removed) return this;
|
2026-05-07 07:44:55 +02:00
|
|
|
return new PersistentOrderedMap<K, V, TStrategy>(newRoot, _strategy, Count - 1);
|
2026-02-01 20:52:23 +01:00
|
|
|
}
|
|
|
|
|
|
2026-05-07 07:44:55 +02:00
|
|
|
public TransientOrderedMap<K, V, TStrategy> ToTransient()
|
2026-02-01 20:52:23 +01:00
|
|
|
{
|
2026-05-07 07:44:55 +02:00
|
|
|
return new TransientOrderedMap<K, V, TStrategy>(_root, _strategy, Count);
|
2026-02-01 20:52:23 +01:00
|
|
|
}
|
|
|
|
|
}
|