hash_test.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2012 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include <cstring>
  10. #include <vector>
  11. #include "test_util/testharness.h"
  12. #include "util/coding.h"
  13. #include "util/hash.h"
  14. using ROCKSDB_NAMESPACE::EncodeFixed32;
  15. using ROCKSDB_NAMESPACE::GetSliceHash64;
  16. using ROCKSDB_NAMESPACE::Hash;
  17. using ROCKSDB_NAMESPACE::Hash64;
  18. using ROCKSDB_NAMESPACE::Lower32of64;
  19. using ROCKSDB_NAMESPACE::Slice;
  20. using ROCKSDB_NAMESPACE::Upper32of64;
  21. // The hash algorithm is part of the file format, for example for the Bloom
  22. // filters. Test that the hash values are stable for a set of random strings of
  23. // varying lengths.
  24. TEST(HashTest, Values) {
  25. constexpr uint32_t kSeed = 0xbc9f1d34; // Same as BloomHash.
  26. EXPECT_EQ(Hash("", 0, kSeed), 3164544308u);
  27. EXPECT_EQ(Hash("\x08", 1, kSeed), 422599524u);
  28. EXPECT_EQ(Hash("\x17", 1, kSeed), 3168152998u);
  29. EXPECT_EQ(Hash("\x9a", 1, kSeed), 3195034349u);
  30. EXPECT_EQ(Hash("\x1c", 1, kSeed), 2651681383u);
  31. EXPECT_EQ(Hash("\x4d\x76", 2, kSeed), 2447836956u);
  32. EXPECT_EQ(Hash("\x52\xd5", 2, kSeed), 3854228105u);
  33. EXPECT_EQ(Hash("\x91\xf7", 2, kSeed), 31066776u);
  34. EXPECT_EQ(Hash("\xd6\x27", 2, kSeed), 1806091603u);
  35. EXPECT_EQ(Hash("\x30\x46\x0b", 3, kSeed), 3808221797u);
  36. EXPECT_EQ(Hash("\x56\xdc\xd6", 3, kSeed), 2157698265u);
  37. EXPECT_EQ(Hash("\xd4\x52\x33", 3, kSeed), 1721992661u);
  38. EXPECT_EQ(Hash("\x6a\xb5\xf4", 3, kSeed), 2469105222u);
  39. EXPECT_EQ(Hash("\x67\x53\x81\x1c", 4, kSeed), 118283265u);
  40. EXPECT_EQ(Hash("\x69\xb8\xc0\x88", 4, kSeed), 3416318611u);
  41. EXPECT_EQ(Hash("\x1e\x84\xaf\x2d", 4, kSeed), 3315003572u);
  42. EXPECT_EQ(Hash("\x46\xdc\x54\xbe", 4, kSeed), 447346355u);
  43. EXPECT_EQ(Hash("\xd0\x7a\x6e\xea\x56", 5, kSeed), 4255445370u);
  44. EXPECT_EQ(Hash("\x86\x83\xd5\xa4\xd8", 5, kSeed), 2390603402u);
  45. EXPECT_EQ(Hash("\xb7\x46\xbb\x77\xce", 5, kSeed), 2048907743u);
  46. EXPECT_EQ(Hash("\x6c\xa8\xbc\xe5\x99", 5, kSeed), 2177978500u);
  47. EXPECT_EQ(Hash("\x5c\x5e\xe1\xa0\x73\x81", 6, kSeed), 1036846008u);
  48. EXPECT_EQ(Hash("\x08\x5d\x73\x1c\xe5\x2e", 6, kSeed), 229980482u);
  49. EXPECT_EQ(Hash("\x42\xfb\xf2\x52\xb4\x10", 6, kSeed), 3655585422u);
  50. EXPECT_EQ(Hash("\x73\xe1\xff\x56\x9c\xce", 6, kSeed), 3502708029u);
  51. EXPECT_EQ(Hash("\x5c\xbe\x97\x75\x54\x9a\x52", 7, kSeed), 815120748u);
  52. EXPECT_EQ(Hash("\x16\x82\x39\x49\x88\x2b\x36", 7, kSeed), 3056033698u);
  53. EXPECT_EQ(Hash("\x59\x77\xf0\xa7\x24\xf4\x78", 7, kSeed), 587205227u);
  54. EXPECT_EQ(Hash("\xd3\xa5\x7c\x0e\xc0\x02\x07", 7, kSeed), 2030937252u);
  55. EXPECT_EQ(Hash("\x31\x1b\x98\x75\x96\x22\xd3\x9a", 8, kSeed), 469635402u);
  56. EXPECT_EQ(Hash("\x38\xd6\xf7\x28\x20\xb4\x8a\xe9", 8, kSeed), 3530274698u);
  57. EXPECT_EQ(Hash("\xbb\x18\x5d\xf4\x12\x03\xf7\x99", 8, kSeed), 1974545809u);
  58. EXPECT_EQ(Hash("\x80\xd4\x3b\x3b\xae\x22\xa2\x78", 8, kSeed), 3563570120u);
  59. EXPECT_EQ(Hash("\x1a\xb5\xd0\xfe\xab\xc3\x61\xb2\x99", 9, kSeed),
  60. 2706087434u);
  61. EXPECT_EQ(Hash("\x8e\x4a\xc3\x18\x20\x2f\x06\xe6\x3c", 9, kSeed),
  62. 1534654151u);
  63. EXPECT_EQ(Hash("\xb6\xc0\xdd\x05\x3f\xc4\x86\x4c\xef", 9, kSeed),
  64. 2355554696u);
  65. EXPECT_EQ(Hash("\x9a\x5f\x78\x0d\xaf\x50\xe1\x1f\x55", 9, kSeed),
  66. 1400800912u);
  67. EXPECT_EQ(Hash("\x22\x6f\x39\x1f\xf8\xdd\x4f\x52\x17\x94", 10, kSeed),
  68. 3420325137u);
  69. EXPECT_EQ(Hash("\x32\x89\x2a\x75\x48\x3a\x4a\x02\x69\xdd", 10, kSeed),
  70. 3427803584u);
  71. EXPECT_EQ(Hash("\x06\x92\x5c\xf4\x88\x0e\x7e\x68\x38\x3e", 10, kSeed),
  72. 1152407945u);
  73. EXPECT_EQ(Hash("\xbd\x2c\x63\x38\xbf\xe9\x78\xb7\xbf\x15", 10, kSeed),
  74. 3382479516u);
  75. }
  76. // The hash algorithm is part of the file format, for example for the Bloom
  77. // filters.
  78. TEST(HashTest, Hash64Misc) {
  79. constexpr uint32_t kSeed = 0; // Same as GetSliceHash64
  80. for (char fill : {'\0', 'a', '1', '\xff'}) {
  81. const size_t max_size = 1000;
  82. const std::string str(max_size, fill);
  83. for (size_t size = 0; size <= max_size; ++size) {
  84. uint64_t here = Hash64(str.data(), size, kSeed);
  85. // Must be same as GetSliceHash64
  86. EXPECT_EQ(here, GetSliceHash64(Slice(str.data(), size)));
  87. // Upper and Lower must reconstruct hash
  88. EXPECT_EQ(here, (uint64_t{Upper32of64(here)} << 32) | Lower32of64(here));
  89. EXPECT_EQ(here, (uint64_t{Upper32of64(here)} << 32) + Lower32of64(here));
  90. EXPECT_EQ(here, (uint64_t{Upper32of64(here)} << 32) ^ Lower32of64(here));
  91. // Seed changes hash value (with high probability)
  92. for (uint64_t var_seed = 1; var_seed != 0; var_seed <<= 1) {
  93. EXPECT_NE(here, Hash64(str.data(), size, var_seed));
  94. }
  95. // Size changes hash value (with high probability)
  96. size_t max_smaller_by = std::min(size_t{30}, size);
  97. for (size_t smaller_by = 1; smaller_by <= max_smaller_by; ++smaller_by) {
  98. EXPECT_NE(here, Hash64(str.data(), size - smaller_by, kSeed));
  99. }
  100. }
  101. }
  102. }
  103. // Test that hash values are "non-trivial" for "trivial" inputs
  104. TEST(HashTest, Hash64Trivial) {
  105. // Thorough test too slow for regression testing
  106. constexpr bool thorough = false;
  107. // For various seeds, make sure hash of empty string is not zero.
  108. constexpr uint64_t max_seed = thorough ? 0x1000000 : 0x10000;
  109. for (uint64_t seed = 0; seed < max_seed; ++seed) {
  110. uint64_t here = Hash64("", 0, seed);
  111. EXPECT_NE(Lower32of64(here), 0u);
  112. EXPECT_NE(Upper32of64(here), 0u);
  113. }
  114. // For standard seed, make sure hash of small strings are not zero
  115. constexpr uint32_t kSeed = 0; // Same as GetSliceHash64
  116. char input[4];
  117. constexpr int max_len = thorough ? 3 : 2;
  118. for (int len = 1; len <= max_len; ++len) {
  119. for (uint32_t i = 0; (i >> (len * 8)) == 0; ++i) {
  120. EncodeFixed32(input, i);
  121. uint64_t here = Hash64(input, len, kSeed);
  122. EXPECT_NE(Lower32of64(here), 0u);
  123. EXPECT_NE(Upper32of64(here), 0u);
  124. }
  125. }
  126. }
  127. // Test that the hash values are stable for a set of random strings of
  128. // varying small lengths.
  129. TEST(HashTest, Hash64SmallValueSchema) {
  130. constexpr uint32_t kSeed = 0; // Same as GetSliceHash64
  131. EXPECT_EQ(Hash64("", 0, kSeed), uint64_t{5999572062939766020u});
  132. EXPECT_EQ(Hash64("\x08", 1, kSeed), uint64_t{583283813901344696u});
  133. EXPECT_EQ(Hash64("\x17", 1, kSeed), uint64_t{16175549975585474943u});
  134. EXPECT_EQ(Hash64("\x9a", 1, kSeed), uint64_t{16322991629225003903u});
  135. EXPECT_EQ(Hash64("\x1c", 1, kSeed), uint64_t{13269285487706833447u});
  136. EXPECT_EQ(Hash64("\x4d\x76", 2, kSeed), uint64_t{6859542833406258115u});
  137. EXPECT_EQ(Hash64("\x52\xd5", 2, kSeed), uint64_t{4919611532550636959u});
  138. EXPECT_EQ(Hash64("\x91\xf7", 2, kSeed), uint64_t{14199427467559720719u});
  139. EXPECT_EQ(Hash64("\xd6\x27", 2, kSeed), uint64_t{12292689282614532691u});
  140. EXPECT_EQ(Hash64("\x30\x46\x0b", 3, kSeed), uint64_t{11404699285340020889u});
  141. EXPECT_EQ(Hash64("\x56\xdc\xd6", 3, kSeed), uint64_t{12404347133785524237u});
  142. EXPECT_EQ(Hash64("\xd4\x52\x33", 3, kSeed), uint64_t{15853805298481534034u});
  143. EXPECT_EQ(Hash64("\x6a\xb5\xf4", 3, kSeed), uint64_t{16863488758399383382u});
  144. EXPECT_EQ(Hash64("\x67\x53\x81\x1c", 4, kSeed),
  145. uint64_t{9010661983527562386u});
  146. EXPECT_EQ(Hash64("\x69\xb8\xc0\x88", 4, kSeed),
  147. uint64_t{6611781377647041447u});
  148. EXPECT_EQ(Hash64("\x1e\x84\xaf\x2d", 4, kSeed),
  149. uint64_t{15290969111616346501u});
  150. EXPECT_EQ(Hash64("\x46\xdc\x54\xbe", 4, kSeed),
  151. uint64_t{7063754590279313623u});
  152. EXPECT_EQ(Hash64("\xd0\x7a\x6e\xea\x56", 5, kSeed),
  153. uint64_t{6384167718754869899u});
  154. EXPECT_EQ(Hash64("\x86\x83\xd5\xa4\xd8", 5, kSeed),
  155. uint64_t{16874407254108011067u});
  156. EXPECT_EQ(Hash64("\xb7\x46\xbb\x77\xce", 5, kSeed),
  157. uint64_t{16809880630149135206u});
  158. EXPECT_EQ(Hash64("\x6c\xa8\xbc\xe5\x99", 5, kSeed),
  159. uint64_t{1249038833153141148u});
  160. EXPECT_EQ(Hash64("\x5c\x5e\xe1\xa0\x73\x81", 6, kSeed),
  161. uint64_t{17358142495308219330u});
  162. EXPECT_EQ(Hash64("\x08\x5d\x73\x1c\xe5\x2e", 6, kSeed),
  163. uint64_t{4237646583134806322u});
  164. EXPECT_EQ(Hash64("\x42\xfb\xf2\x52\xb4\x10", 6, kSeed),
  165. uint64_t{4373664924115234051u});
  166. EXPECT_EQ(Hash64("\x73\xe1\xff\x56\x9c\xce", 6, kSeed),
  167. uint64_t{12012981210634596029u});
  168. EXPECT_EQ(Hash64("\x5c\xbe\x97\x75\x54\x9a\x52", 7, kSeed),
  169. uint64_t{5716522398211028826u});
  170. EXPECT_EQ(Hash64("\x16\x82\x39\x49\x88\x2b\x36", 7, kSeed),
  171. uint64_t{15604531309862565013u});
  172. EXPECT_EQ(Hash64("\x59\x77\xf0\xa7\x24\xf4\x78", 7, kSeed),
  173. uint64_t{8601330687345614172u});
  174. EXPECT_EQ(Hash64("\xd3\xa5\x7c\x0e\xc0\x02\x07", 7, kSeed),
  175. uint64_t{8088079329364056942u});
  176. EXPECT_EQ(Hash64("\x31\x1b\x98\x75\x96\x22\xd3\x9a", 8, kSeed),
  177. uint64_t{9844314944338447628u});
  178. EXPECT_EQ(Hash64("\x38\xd6\xf7\x28\x20\xb4\x8a\xe9", 8, kSeed),
  179. uint64_t{10973293517982163143u});
  180. EXPECT_EQ(Hash64("\xbb\x18\x5d\xf4\x12\x03\xf7\x99", 8, kSeed),
  181. uint64_t{9986007080564743219u});
  182. EXPECT_EQ(Hash64("\x80\xd4\x3b\x3b\xae\x22\xa2\x78", 8, kSeed),
  183. uint64_t{1729303145008254458u});
  184. EXPECT_EQ(Hash64("\x1a\xb5\xd0\xfe\xab\xc3\x61\xb2\x99", 9, kSeed),
  185. uint64_t{13253403748084181481u});
  186. EXPECT_EQ(Hash64("\x8e\x4a\xc3\x18\x20\x2f\x06\xe6\x3c", 9, kSeed),
  187. uint64_t{7768754303876232188u});
  188. EXPECT_EQ(Hash64("\xb6\xc0\xdd\x05\x3f\xc4\x86\x4c\xef", 9, kSeed),
  189. uint64_t{12439346786701492u});
  190. EXPECT_EQ(Hash64("\x9a\x5f\x78\x0d\xaf\x50\xe1\x1f\x55", 9, kSeed),
  191. uint64_t{10841838338450144690u});
  192. EXPECT_EQ(Hash64("\x22\x6f\x39\x1f\xf8\xdd\x4f\x52\x17\x94", 10, kSeed),
  193. uint64_t{12883919702069153152u});
  194. EXPECT_EQ(Hash64("\x32\x89\x2a\x75\x48\x3a\x4a\x02\x69\xdd", 10, kSeed),
  195. uint64_t{12692903507676842188u});
  196. EXPECT_EQ(Hash64("\x06\x92\x5c\xf4\x88\x0e\x7e\x68\x38\x3e", 10, kSeed),
  197. uint64_t{6540985900674032620u});
  198. EXPECT_EQ(Hash64("\xbd\x2c\x63\x38\xbf\xe9\x78\xb7\xbf\x15", 10, kSeed),
  199. uint64_t{10551812464348219044u});
  200. }
  201. std::string Hash64TestDescriptor(const char *repeat, size_t limit) {
  202. const char *mod61_encode =
  203. "abcdefghijklmnopqrstuvwxyz123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  204. std::string input;
  205. while (input.size() < limit) {
  206. input.append(repeat);
  207. }
  208. std::string rv;
  209. for (size_t i = 0; i < limit; ++i) {
  210. uint64_t h = GetSliceHash64(Slice(input.data(), i));
  211. rv.append(1, mod61_encode[static_cast<size_t>(h % 61)]);
  212. }
  213. return rv;
  214. }
  215. // XXH3p changes its algorithm for various sizes up through 250 bytes, so
  216. // we need to check the stability of larger sizes also.
  217. TEST(HashTest, Hash64LargeValueSchema) {
  218. // Each of these derives a "descriptor" from the hash values for all
  219. // lengths up to 430.
  220. // Note that "c" is common for the zero-length string.
  221. EXPECT_EQ(
  222. Hash64TestDescriptor("foo", 430),
  223. "cRhyWsY67B6klRA1udmOuiYuX7IthyGBKqbeosz2hzVglWCmQx8nEdnpkvPfYX56Up2OWOTV"
  224. "lTzfAoYwvtqKzjD8E9xttR2unelbXbIV67NUe6bOO23BxaSFRcA3njGu5cUWfgwOqNoTsszp"
  225. "uPvKRP6qaUR5VdoBkJUCFIefd7edlNK5mv6JYWaGdwxehg65hTkTmjZoPKxTZo4PLyzbL9U4"
  226. "xt12ITSfeP2MfBHuLI2z2pDlBb44UQKVMx27LEoAHsdLp3WfWfgH3sdRBRCHm33UxCM4QmE2"
  227. "xJ7gqSvNwTeH7v9GlC8zWbGroyD3UVNeShMLx29O7tH1biemLULwAHyIw8zdtLMDpEJ8m2ic"
  228. "l6Lb4fDuuFNAs1GCVUthjK8CV8SWI8Rsz5THSwn5CGhpqUwSZcFknjwWIl5rNCvDxXJqYr");
  229. // Note that "1EeRk" is common for "Rocks"
  230. EXPECT_EQ(
  231. Hash64TestDescriptor("Rocks", 430),
  232. "c1EeRkrzgOYWLA8PuhJrwTePJewoB44WdXYDfhbk3ZxTqqg25WlPExDl7IKIQLJvnA6gJxxn"
  233. "9TCSLkFGfJeXehaSS1GBqWSzfhEH4VXiXIUCuxJXxtKXcSC6FrNIQGTZbYDiUOLD6Y5inzrF"
  234. "9etwQhXUBanw55xAUdNMFQAm2GjJ6UDWp2mISLiMMkLjANWMKLaZMqaFLX37qB4MRO1ooVRv"
  235. "zSvaNRSCLxlggQCasQq8icWjzf3HjBlZtU6pd4rkaUxSzHqmo9oM5MghbU5Rtxg8wEfO7lVN"
  236. "5wdMONYecslQTwjZUpO1K3LDf3K3XK6sUXM6ShQQ3RHmMn2acB4YtTZ3QQcHYJSOHn2DuWpa"
  237. "Q8RqzX5lab92YmOLaCdOHq1BPsM7SIBzMdLgePNsJ1vvMALxAaoDUHPxoFLO2wx18IXnyX");
  238. EXPECT_EQ(
  239. Hash64TestDescriptor("RocksDB", 430),
  240. "c1EeRkukbkb28wLTahwD2sfUhZzaBEnF8SVrxnPVB6A7b8CaAl3UKsDZISF92GSq2wDCukOq"
  241. "Jgrsp7A3KZhDiLW8dFXp8UPqPxMCRlMdZeVeJ2dJxrmA6cyt99zkQFj7ELbut6jAeVqARFnw"
  242. "fnWVXOsaLrq7bDCbMcns2DKvTaaqTCLMYxI7nhtLpFN1jR755FRQFcOzrrDbh7QhypjdvlYw"
  243. "cdAMSZgp9JMHxbM23wPSuH6BOFgxejz35PScZfhDPvTOxIy1jc3MZsWrMC3P324zNolO7JdW"
  244. "CX2I5UDKjjaEJfxbgVgJIXxtQGlmj2xkO5sPpjULQV4X2HlY7FQleJ4QRaJIB4buhCA4vUTF"
  245. "eMFlxCIYUpTCsal2qsmnGOWa8WCcefrohMjDj1fjzSvSaQwlpyR1GZHF2uPOoQagiCpHpm");
  246. }
  247. TEST(Fastrange32Test, Values) {
  248. using ROCKSDB_NAMESPACE::fastrange32;
  249. // Zero range
  250. EXPECT_EQ(fastrange32(0, 0), 0U);
  251. EXPECT_EQ(fastrange32(123, 0), 0U);
  252. EXPECT_EQ(fastrange32(0xffffffff, 0), 0U);
  253. // One range
  254. EXPECT_EQ(fastrange32(0, 1), 0U);
  255. EXPECT_EQ(fastrange32(123, 1), 0U);
  256. EXPECT_EQ(fastrange32(0xffffffff, 1), 0U);
  257. // Two range
  258. EXPECT_EQ(fastrange32(0, 2), 0U);
  259. EXPECT_EQ(fastrange32(123, 2), 0U);
  260. EXPECT_EQ(fastrange32(0x7fffffff, 2), 0U);
  261. EXPECT_EQ(fastrange32(0x80000000, 2), 1U);
  262. EXPECT_EQ(fastrange32(0xffffffff, 2), 1U);
  263. // Seven range
  264. EXPECT_EQ(fastrange32(0, 7), 0U);
  265. EXPECT_EQ(fastrange32(123, 7), 0U);
  266. EXPECT_EQ(fastrange32(613566756, 7), 0U);
  267. EXPECT_EQ(fastrange32(613566757, 7), 1U);
  268. EXPECT_EQ(fastrange32(1227133513, 7), 1U);
  269. EXPECT_EQ(fastrange32(1227133514, 7), 2U);
  270. // etc.
  271. EXPECT_EQ(fastrange32(0xffffffff, 7), 6U);
  272. // Big
  273. EXPECT_EQ(fastrange32(1, 0x80000000), 0U);
  274. EXPECT_EQ(fastrange32(2, 0x80000000), 1U);
  275. EXPECT_EQ(fastrange32(4, 0x7fffffff), 1U);
  276. EXPECT_EQ(fastrange32(4, 0x80000000), 2U);
  277. EXPECT_EQ(fastrange32(0xffffffff, 0x7fffffff), 0x7ffffffeU);
  278. EXPECT_EQ(fastrange32(0xffffffff, 0x80000000), 0x7fffffffU);
  279. }
  280. TEST(Fastrange64Test, Values) {
  281. using ROCKSDB_NAMESPACE::fastrange64;
  282. // Zero range
  283. EXPECT_EQ(fastrange64(0, 0), 0U);
  284. EXPECT_EQ(fastrange64(123, 0), 0U);
  285. EXPECT_EQ(fastrange64(0xffffFFFF, 0), 0U);
  286. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 0), 0U);
  287. // One range
  288. EXPECT_EQ(fastrange64(0, 1), 0U);
  289. EXPECT_EQ(fastrange64(123, 1), 0U);
  290. EXPECT_EQ(fastrange64(0xffffFFFF, 1), 0U);
  291. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 1), 0U);
  292. // Two range
  293. EXPECT_EQ(fastrange64(0, 2), 0U);
  294. EXPECT_EQ(fastrange64(123, 2), 0U);
  295. EXPECT_EQ(fastrange64(0xffffFFFF, 2), 0U);
  296. EXPECT_EQ(fastrange64(0x7fffFFFFffffFFFF, 2), 0U);
  297. EXPECT_EQ(fastrange64(0x8000000000000000, 2), 1U);
  298. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 2), 1U);
  299. // Seven range
  300. EXPECT_EQ(fastrange64(0, 7), 0U);
  301. EXPECT_EQ(fastrange64(123, 7), 0U);
  302. EXPECT_EQ(fastrange64(0xffffFFFF, 7), 0U);
  303. EXPECT_EQ(fastrange64(2635249153387078802, 7), 0U);
  304. EXPECT_EQ(fastrange64(2635249153387078803, 7), 1U);
  305. EXPECT_EQ(fastrange64(5270498306774157604, 7), 1U);
  306. EXPECT_EQ(fastrange64(5270498306774157605, 7), 2U);
  307. EXPECT_EQ(fastrange64(0x7fffFFFFffffFFFF, 7), 3U);
  308. EXPECT_EQ(fastrange64(0x8000000000000000, 7), 3U);
  309. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 7), 6U);
  310. // Big but 32-bit range
  311. EXPECT_EQ(fastrange64(0x100000000, 0x80000000), 0U);
  312. EXPECT_EQ(fastrange64(0x200000000, 0x80000000), 1U);
  313. EXPECT_EQ(fastrange64(0x400000000, 0x7fffFFFF), 1U);
  314. EXPECT_EQ(fastrange64(0x400000000, 0x80000000), 2U);
  315. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 0x7fffFFFF), 0x7fffFFFEU);
  316. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 0x80000000), 0x7fffFFFFU);
  317. // Big, > 32-bit range
  318. #if SIZE_MAX == UINT64_MAX
  319. EXPECT_EQ(fastrange64(0x7fffFFFFffffFFFF, 0x4200000002), 0x2100000000U);
  320. EXPECT_EQ(fastrange64(0x8000000000000000, 0x4200000002), 0x2100000001U);
  321. EXPECT_EQ(fastrange64(0x0000000000000000, 420000000002), 0U);
  322. EXPECT_EQ(fastrange64(0x7fffFFFFffffFFFF, 420000000002), 210000000000U);
  323. EXPECT_EQ(fastrange64(0x8000000000000000, 420000000002), 210000000001U);
  324. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 420000000002), 420000000001U);
  325. EXPECT_EQ(fastrange64(0xffffFFFFffffFFFF, 0xffffFFFFffffFFFF),
  326. 0xffffFFFFffffFFFEU);
  327. #endif
  328. }
  329. // for inspection of disassembly
  330. uint32_t fastrange32(uint32_t hash, uint32_t range) {
  331. return ROCKSDB_NAMESPACE::fastrange32(hash, range);
  332. }
  333. // for inspection of disassembly
  334. size_t fastrange64(uint64_t hash, size_t range) {
  335. return ROCKSDB_NAMESPACE::fastrange64(hash, range);
  336. }
  337. int main(int argc, char** argv) {
  338. ::testing::InitGoogleTest(&argc, argv);
  339. return RUN_ALL_TESTS();
  340. }