以确定的方式获得新的身份

时间:2017-02-01 21:14:31

标签: c# deterministic

我在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。

1 个答案:

答案 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);
    }
}