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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For anyone interested, I could have used
Unsafe.As
instead ofMemoryMarshal.Cast
and it would be slightly faster, but does not do bounds checking at runtime, hence theUnsafe
name (even though it can be used from safe code blocks).