我在C#中有一个IImmutableDictionary<int, MyType>
。在我的程序执行期间,我想根据一些命令添加和删除MyType
个实例:
public sealed class AddMyTypeCommand : ICommand
{
public readonly MyType myTypeToAdd;
// etc...
}
public sealed class RemoveMyTypeCommand : ICommand
{
public readonly int keyToRemove;
// etc...
}
添加MyType
时,我想生成一个新的int
密钥,该密钥尚未包含在字典中。
我认为我永远不会用完int
,因为密钥可能会被移除并在以后重复使用。
主要的问题是我希望这个过程是 deterministic 。对于给定的ICommand
个流,代码必须在不同的机器上执行相同的操作(并生成相同的密钥!)。
实现密钥生成步骤的强大,可维护和高效的方法是什么?
例如,缓慢的方法是:从int.MinValue
开始,向上走,直到找到新的id。
答案 0 :(得分:0)
如果您知道除了添加之外不会删除太多,您可以尝试在队列中存储所有空洞,并根据队列是否为空来确定密钥。因此,如果没有孔,您的词典将自动递增键,如果有孔,则返回填充。
class ImmutableDictionary<T>
{
private readonly Dictionary<int, T> _dict = new Dictionary<int, T>();
private readonly Queue<int> _holes = new Queue<int>();
private int _nextInt = 0; //what is next integer to assign, I'm starting at 0, but can be int.MinValue
private int AssignKey()
{
//if we have a hole, use that as the next key. Otherwise use the largest value we haven't assigned yet, and then increment that value by 1
return _holes.Count != 0 ? _holes.Dequeue() : _nextInt++;
}
public void Add(T input)
{
_dict.Add(AssignKey(), input);
}
public void Remove(int key)
{
if (_dict.Remove(key)) //if a remove is successful, we should add a hole
//you can extend the logic here to not add a hole if you are removing something equal to _nextInt - 1.
_holes.Enqueue(key);
}
}