Last active
July 2, 2018 07:23
-
-
Save slang25/eff66d1863e2b3c33fd82eee54b87f37 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
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
@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.