Skip to content

Instantly share code, notes, and snippets.

@Masstronaut
Last active March 23, 2017 07:48
Show Gist options
  • Save Masstronaut/7cad21388a4613e13acb9535d18f7c16 to your computer and use it in GitHub Desktop.
Save Masstronaut/7cad21388a4613e13acb9535d18f7c16 to your computer and use it in GitHub Desktop.
Compile time implementation of the MurmurHash2A 64bit version for 64bit architecture.
// All content copyright (C) Allan Deutsch 2017. All rights reserved.
#pragma once
#include <cstdint>
// According to the top post here: http://softwareengineering.stackexchange.com/a/145633
// murmur2 is the best hash for speed and random distribution.
// This is a constexpr implementation of Murmur2A, a hash algorithm designed by Austin Appleby.
// This version is optimized for 64bit architectures.
constexpr uint64_t murmur2a_64_ct( const char *str, unsigned long size, uint64_t seed ) {
constexpr uint64_t prime{ 0xc6a4a7935bd1e995ull };
constexpr uint32_t shift1{ 19 };
constexpr uint32_t shift2{ 37 };
uint64_t hash{ seed ^ ( size * prime ) };
const uint64_t *data{ ( const uint64_t * )str };
const uint64_t *end{ data + ( size / 8 ) };
while( data != end ) {
uint64_t word{ *data++ };
word *= prime;
word ^= word >> shift1;
word *= prime;
hash ^= word;
hash *= prime;
}
const unsigned char *byte_data{ ( const unsigned char * )data };
switch( size & 7 ) {
case 7: hash ^= ( ( uint64_t )byte_data[ 6 ] ) << 48;
case 6: hash ^= ( ( uint64_t )byte_data[ 5 ] ) << 40;
case 5: hash ^= ( ( uint64_t )byte_data[ 4 ] ) << 32;
case 4: hash ^= ( ( uint64_t )byte_data[ 3 ] ) << 24;
case 3: hash ^= ( ( uint64_t )byte_data[ 2 ] ) << 16;
case 2: hash ^= ( ( uint64_t )byte_data[ 1 ] ) << 8;
case 1: hash ^= ( ( uint64_t )byte_data[ 0 ] );
}
hash ^= hash >> shift1;
hash *= prime;
hash ^= hash >> shift2;
return hash;
}
// User defined literal conversion to convert a string in the form "foo"_hash to the corresponding Murmur2A hash value
constexpr uint64_t operator""_hash( const char *str, unsigned long size ) {
constexpr uint64_t seed_prime{ 0xFFFFFFFFFFFFFFC5ull };
return murmur2a_64_ct( str, size, seed_prime );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment