Caching 如何从多个键创建缓存键?

Caching 如何从多个键创建缓存键?,caching,Caching,我有一个方法,我将缓存其输出。它需要四个参数字符串,字符串,int,以及WindowsIdentity。我需要根据这四个参数创建一个缓存密钥。最好是: 将它们作为字符串连接在一起并使用该键 var key = string.Concat(string1, string2, int1.ToString(), identity.ToString()); 或 将他们的散列码进行异或运算 var key = string1.GetHashCode() ^ string2.GetHashCode() ^

我有一个方法,我将缓存其输出。它需要四个参数<代码>字符串,
字符串
int
,以及
WindowsIdentity
。我需要根据这四个参数创建一个缓存密钥。最好是:

将它们作为字符串连接在一起并使用该键

var key = string.Concat(string1, string2, int1.ToString(), identity.ToString());

将他们的散列码进行异或运算

var key = string1.GetHashCode() ^ string2.GetHashCode() ^ int1.GetHashCode() ^ identity.GetHashCode();

还是别的什么?这有关系吗?在我的特殊情况下,这些键将进入一个哈希表(C#v1)

使用符合查找键语义的任何内容,框架将处理散列/重新散列/存储桶的细节。(我过去有人告诉我我错了,所以可能会在这里再次发生,我们拭目以待)

我会对后者有点紧张,因为你的钥匙很可能会发生碰撞。这可能会导致您为记录检索不正确的数据(根据应用程序的使用情况,会产生严重的安全/隐私问题)


密钥的主要目标是保持唯一性,因此请消除不能确保这一点的方法,并从其余方法中选择最佳方法。

创建一个封装这四个值的新类型。例如:

public sealed class User
{
    private readonly string name;
    private readonly string login;
    private readonly int points;
    private readonly WindowsIdentity identity;

    public User(string name, string login, int points,
                WindowsIdentity identity)
    {
        this.name = name;
        this.login = login;
        this.points = points;
        this.identity = identity;
    }

    public string Name { get { return name; } }
    public string Login { get { return login; } }
    public int Points { get { return points; } }
    public WindowsIdentity Identity { get { return identity; } }

    public override bool Equals(object other)
    {
        User otherUser = other as User;
        if (otherUser == null)
        {
            return false;
        }
        return name == otherUser.name &&
               login == otherUser.login &&
               points == otherUser.points &&
               identity.Equals(otherUser.identity);
    }

    public override int GetHashCode()
    {
        int hash = 17;
        hash = hash * 31 + name.GetHashCode();
        hash = hash * 31 + login.GetHashCode();
        hash = hash * 31 + points.GetHashCode();
        hash = hash * 31 + identity.GetHashCode();
        return hash;
    }
}
请注意,这假设
WindowsIdentity
适当地覆盖
Equals
GetHashCode
,或者您对引用类型的相等性感到满意


这种方法比您的任何一种建议都要健壮得多——例如,在您的第一种方法中,两个字符串对“xy”、“z”和“x”、“yz”将最终形成相同的缓存键(如果int和identity相同),而它们不应该形成相同的缓存键。第二种方法更可能导致意外的哈希冲突。

所有哈希解决方案都有密钥冲突的风险。XOR是一个特别糟糕的哈希算法,它证明了这一点。我更喜欢你的第一个想法:按顺序排列键,但你应该添加一个分隔符来防止出现这种情况(“xy”+“z”==“x”+“yz”)

另请参见

+1——刚刚遇到了一个例子,其中XOR’ing 3x原语字段导致约5%的冲突/失败率