From 16dadbc8371c84184b36706131d5cfed9502f699 Mon Sep 17 00:00:00 2001
From: Amul Sul <sulamul@gmail.com>
Date: Mon, 23 Oct 2017 18:32:48 +0530
Subject: [PATCH] add hash_combine functions in SMHasher

---
 src/CityTest.cpp | 30 ++++++++++++++++++++++++++++++
 src/Hashes.h     |  2 ++
 src/PMurHash.c   |  1 -
 src/main.cpp     |  2 ++
 4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/CityTest.cpp b/src/CityTest.cpp
index 4190cc8..0259724 100644
--- a/src/CityTest.cpp
+++ b/src/CityTest.cpp
@@ -13,3 +13,33 @@ void CityHash128_test ( const void * key, int len, uint32_t seed, void * out )
 
   *(uint128*)out = CityHash128WithSeed((const char*)key,len,s);
 }
+
+void hash_combine32(const void *key, int len, uint32_t seed, void *out)
+{
+	 uint32_t a;
+	 uint32_t b;
+	 uint64 h;
+
+	 CityHash64_test(key, len, seed, &h);
+	 a = (uint32_t) (h);
+	 b = (uint32_t) (h >> 32);
+
+	/*  0x9e3779b9 is the golden ratio reciprocal */
+	 a ^= b + 0x9e3779b9 + (a << 6) + (a >> 2);
+
+	 *(uint32_t*)out = a;
+}
+void hash_combine64(const void *key, int len, uint32_t seed, void *out)
+{
+	 uint64 a;
+	 uint64 b;
+	 uint128 h;
+
+	 CityHash128_test(key, len, seed, &h);
+	 a = Uint128Low64(h);
+	 b = Uint128High64(h);
+
+	 a ^= b + 0x49A0F4DD15E5A8E3 + (a << 54) + (a >> 7);
+
+	 *(uint64*)out = a;
+}
diff --git a/src/Hashes.h b/src/Hashes.h
index 6c04ae1..951be61 100644
--- a/src/Hashes.h
+++ b/src/Hashes.h
@@ -36,6 +36,8 @@ void MurmurOAAT_test       ( const void * key, int len, uint32_t seed, void * ou
 void Crap8_test            ( const void * key, int len, uint32_t seed, void * out );
 void CityHash128_test      ( const void * key, int len, uint32_t seed, void * out );
 void CityHash64_test       ( const void * key, int len, uint32_t seed, void * out );
+void hash_combine32		   ( const void * key, int len, uint32_t seed, void * out );
+void hash_combine64		   ( const void * key, int len, uint32_t seed, void * out );
 
 void SpookyHash32_test     ( const void * key, int len, uint32_t seed, void * out );
 void SpookyHash64_test     ( const void * key, int len, uint32_t seed, void * out );
diff --git a/src/PMurHash.c b/src/PMurHash.c
index 0175012..8697a5d 100644
--- a/src/PMurHash.c
+++ b/src/PMurHash.c
@@ -313,5 +313,4 @@ void PMurHash32_test(const void *key, int len, uint32_t seed, void *out)
   h1 = PMurHash32_Result(h1, carry, len);
   *(uint32_t*)out = h1;
 }
-
 /*---------------------------------------------------------------------------*/
diff --git a/src/main.cpp b/src/main.cpp
index 678ddb2..7823acb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -80,6 +80,8 @@ HashInfo g_hashes[] =
   { MurmurHash3_x64_128, 128, 0x6384BA69, "Murmur3F",    "MurmurHash3 for x64, 128-bit" },
 
   { PMurHash32_test,      32, 0xB0F57EE3, "PMurHash32",  "Shane Day's portable-ized MurmurHash3 for x86, 32-bit." },
+  { hash_combine32,       32, 0x83D5F11A, "hash_combine32",  "test hash combine 32 pg function." },
+  { hash_combine64,       64, 0x3B439A64, "hash_combine64",  "test hash combine 64 pg function." },
 };
 
 HashInfo * findHash ( const char * name )
-- 
2.14.1

