How to create a cache key from multiple keys?

I have a method whose output I will cache. It takes four parameters; string , string , int and WindowsIdentity . I need to create a cache key based on these four parameters. The best thing:

Combine them all together as strings and use this key?

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

Or

Xor along with its hash codes?

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

Or something else? Does it matter? In my particular case, these keys will just go into a Hashtable (C # v1).

+4
source share
4 answers

Create a new type that encapsulates four values. For instance:

 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; } } 

Note that this assumes that WindowsIdentity overrides Equals and GetHashCode accordingly - or that you are happy with the equality of the reference type.

This approach is much more reliable than any of your suggestions - for example, in your first approach, two pairs of lines "xy", "z" and "x", "yz" ultimately form the same cache key (if int and identity match), while they should not. The second approach is likely to lead to random hash collisions.

+8
source

I would be a little nervous about the latter, because there is little chance that your keys will collide. This can lead to the extraction of incorrect recording data (with serious security / privacy implications depending on the use of your application).

The main goal of your key is to be unique, so exclude methods that do not guarantee that it is, and choose the best from the rest.

+2
source

All hashing solutions are at risk of key collisions. XOR demonstrates this by being a particularly lousy hashing algorithm. I prefer your first thought: arrange the keys in order, but you must add a separator to prevent the case ("xy" + "z" == "x" + "yz")

See also @ Multiple Key Caching

+1
source

Use what you want that matches the key semantics, and the structure will handle the hash / rehash / bucket details from there. (I had people who tell me that I am wrong in the past, so maybe they will happen again here, we will see)

0
source

Source: https://habr.com/ru/post/1316691/


All Articles