2 * Copyright 2012 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "folly/Hash.h"
18 #include "folly/MapUtil.h"
19 #include <gtest/gtest.h>
21 #include <unordered_map>
23 using namespace folly::hash;
26 const char* s1 = "hello, world!";
27 const uint32_t s1_res = 3180823791ul;
28 EXPECT_EQ(fnv32(s1), s1_res);
29 EXPECT_EQ(fnv32(s1), fnv32_buf(s1, strlen(s1)));
31 const char* s2 = "monkeys! m0nk3yz! ev3ry \\/\\/here~~~~";
32 const uint32_t s2_res = 194407565ul;
33 EXPECT_EQ(fnv32(s2), s2_res);
34 EXPECT_EQ(fnv32(s2), fnv32_buf(s2, strlen(s2)));
37 const uint32_t s3_res = 216613626ul;
38 EXPECT_EQ(fnv32(s3), s3_res);
39 EXPECT_EQ(fnv32(s3), fnv32_buf(s3, strlen(s3)));
43 const char* s1 = "hello, world!";
44 const uint64_t s1_res = 13991426986746681734ULL;
45 EXPECT_EQ(fnv64(s1), s1_res);
46 EXPECT_EQ(fnv64(s1), fnv64_buf(s1, strlen(s1)));
48 const char* s2 = "monkeys! m0nk3yz! ev3ry \\/\\/here~~~~";
49 const uint64_t s2_res = 6091394665637302478ULL;
50 EXPECT_EQ(fnv64(s2), s2_res);
51 EXPECT_EQ(fnv64(s2), fnv64_buf(s2, strlen(s2)));
54 const uint64_t s3_res = 14695981039346656037ULL;
55 EXPECT_EQ(fnv64(s3), s3_res);
56 EXPECT_EQ(fnv64(s3), fnv64_buf(s3, strlen(s3)));
58 // note: Use fnv64_buf to make a single hash value from multiple
60 const char* t4_a = "E Pluribus";
61 int64_t t4_b = 0xF1E2D3C4B5A69788;
62 int32_t t4_c = 0xAB12CD34;
63 const char* t4_d = "Unum";
64 uint64_t t4_res = 15571330457339273965ULL;
65 uint64_t t4_hash1 = fnv64_buf(t4_a,
67 uint64_t t4_hash2 = fnv64_buf(reinterpret_cast<void*>(&t4_b),
70 uint64_t t4_hash3 = fnv64_buf(reinterpret_cast<void*>(&t4_c),
73 uint64_t t4_hash4 = fnv64_buf(t4_d,
76 EXPECT_EQ(t4_hash4, t4_res);
77 // note: These are probabalistic, not determinate, but c'mon.
78 // These hash values should be different, or something's not
80 EXPECT_NE(t4_hash1, t4_hash4);
81 EXPECT_NE(t4_hash2, t4_hash4);
82 EXPECT_NE(t4_hash3, t4_hash4);
86 const char* s1 = "hello, world!";
87 const uint32_t s1_res = 2918802987ul;
88 EXPECT_EQ(hsieh_hash32(s1), s1_res);
89 EXPECT_EQ(hsieh_hash32(s1), hsieh_hash32_buf(s1, strlen(s1)));
91 const char* s2 = "monkeys! m0nk3yz! ev3ry \\/\\/here~~~~";
92 const uint32_t s2_res = 47373213ul;
93 EXPECT_EQ(hsieh_hash32(s2), s2_res);
94 EXPECT_EQ(hsieh_hash32(s2), hsieh_hash32_buf(s2, strlen(s2)));
97 const uint32_t s3_res = 0;
98 EXPECT_EQ(hsieh_hash32(s3), s3_res);
99 EXPECT_EQ(hsieh_hash32(s3), hsieh_hash32_buf(s3, strlen(s3)));
102 TEST(Hash, TWang_Mix64) {
103 uint64_t i1 = 0x78a87873e2d31dafULL;
104 uint64_t i1_res = 3389151152926383528ULL;
105 EXPECT_EQ(i1_res, twang_mix64(i1));
106 EXPECT_EQ(i1, twang_unmix64(i1_res));
108 uint64_t i2 = 0x0123456789abcdefULL;
109 uint64_t i2_res = 3061460455458984563ull;
110 EXPECT_EQ(i2_res, twang_mix64(i2));
111 EXPECT_EQ(i2, twang_unmix64(i2_res));
115 void checkTWang(uint64_t r) {
116 uint64_t result = twang_mix64(r);
117 EXPECT_EQ(r, twang_unmix64(result));
121 TEST(Hash, TWang_Unmix64) {
122 // We'll try (1 << i), (1 << i) + 1, (1 << i) - 1
123 for (int i = 1; i < 64; i++) {
124 checkTWang((1U << i) - 1);
126 checkTWang((1U << i) + 1);
130 TEST(Hash, TWang_32From64) {
131 uint64_t i1 = 0x78a87873e2d31dafULL;
132 uint32_t i1_res = 1525586863ul;
133 EXPECT_EQ(twang_32from64(i1), i1_res);
135 uint64_t i2 = 0x0123456789abcdefULL;
136 uint32_t i2_res = 2918899159ul;
137 EXPECT_EQ(twang_32from64(i2), i2_res);
140 TEST(Hash, Jenkins_Rev_Mix32) {
141 uint32_t i1 = 3805486511ul;
142 uint32_t i1_res = 381808021ul;
143 EXPECT_EQ(i1_res, jenkins_rev_mix32(i1));
144 EXPECT_EQ(i1, jenkins_rev_unmix32(i1_res));
146 uint32_t i2 = 2309737967ul;
147 uint32_t i2_res = 1834777923ul;
148 EXPECT_EQ(i2_res, jenkins_rev_mix32(i2));
149 EXPECT_EQ(i2, jenkins_rev_unmix32(i2_res));
153 void checkJenkins(uint32_t r) {
154 uint32_t result = jenkins_rev_mix32(r);
155 EXPECT_EQ(r, jenkins_rev_unmix32(result));
159 TEST(Hash, Jenkins_Rev_Unmix32) {
160 // We'll try (1 << i), (1 << i) + 1, (1 << i) - 1
161 for (int i = 1; i < 32; i++) {
162 checkJenkins((1U << i) - 1);
163 checkJenkins(1U << i);
164 checkJenkins((1U << i) + 1);
169 // Basically just confirms that things compile ok.
170 std::unordered_map<int32_t,int32_t,folly::hasher<int32_t>> m;
171 m.insert(std::make_pair(4, 5));
172 EXPECT_EQ(get_default(m, 4), 5);
175 TEST(Hash, hash_combine) {
176 EXPECT_NE(hash_combine(1, 2), hash_combine(2, 1));