Skip to content

Instantly share code, notes, and snippets.

@slang25
Last active July 2, 2018 07:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slang25/eff66d1863e2b3c33fd82eee54b87f37 to your computer and use it in GitHub Desktop.
Save slang25/eff66d1863e2b3c33fd82eee54b87f37 to your computer and use it in GitHub Desktop.
public static int Hash(ReadOnlySpan<byte> data, uint seed)
{
const uint c1 = 0xcc9e2d51;
const uint c2 = 0x1b873593;
var ints = MemoryMarshal.Cast<byte,uint>(data);
var h1 = seed;
var end = (data.Length >> 2); // /= 4
uint k1;
for (int i = 0; i < end; i++)
{
/* bitmagic hash */
k1 = ints[i];
k1 *= c1;
k1 = Rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = Rotl32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
// handle remainder
k1 = 0;
var remainder = data.Length - end * sizeof(uint);
if (remainder > 0)
{
for (int i = 0; i < remainder; i++)
{
k1 = k1 << 8;
k1 = data[i];
}
k1 *= c1;
k1 = Rotl32(k1, 15);
k1 *= c2;
h1 ^= k1;
}
h1 ^= (uint)data.Length;
h1 = Fmix(h1);
return (int)h1;
}
@pshrosbree
Copy link

What is the purpose of line 30? You overwrite the value in the next line.

@slang25
Copy link
Author

slang25 commented Jul 2, 2018

@pshrosbree that's a good question, I'm not sure, this is just a modified version of the code from this post. I agree, it seems redundant.

@slang25
Copy link
Author

slang25 commented Jul 2, 2018

For anyone interested, I could have used Unsafe.As instead of MemoryMarshal.Cast and it would be slightly faster, but does not do bounds checking at runtime, hence the Unsafe name (even though it can be used from safe code blocks).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment