1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license.
3
4#pragma once
5
6#include <cstdint>
7#include <cstring>
8#include <stdexcept>
9#include <string>
10
11namespace FASTER {
12namespace core {
13
14class Utility {
15 public:
16 static inline uint64_t Rotr64(uint64_t x, std::size_t n) {
17 return (((x) >> n) | ((x) << (64 - n)));
18 }
19
20 static inline uint64_t GetHashCode(uint64_t input) {
21 uint64_t local_rand = input;
22 uint64_t local_rand_hash = 8;
23 local_rand_hash = 40343 * local_rand_hash + ((local_rand) & 0xFFFF);
24 local_rand_hash = 40343 * local_rand_hash + ((local_rand >> 16) & 0xFFFF);
25 local_rand_hash = 40343 * local_rand_hash + ((local_rand >> 32) & 0xFFFF);
26 local_rand_hash = 40343 * local_rand_hash + (local_rand >> 48);
27 local_rand_hash = 40343 * local_rand_hash;
28 return Rotr64(local_rand_hash, 43);
29 //Func<long, long> hash =
30 // e => 40343 * (40343 * (40343 * (40343 * (40343 * 8 + (long)((e) & 0xFFFF)) + (long)((e >> 16) & 0xFFFF)) + (long)((e >> 32) & 0xFFFF)) + (long)(e >> 48));
31 }
32
33 static inline uint64_t HashBytes(const uint16_t* str, size_t len) {
34 // 40343 is a "magic constant" that works well,
35 // 38299 is another good value.
36 // Both are primes and have a good distribution of bits.
37 const uint64_t kMagicNum = 40343;
38 uint64_t hashState = len;
39
40 for(size_t idx = 0; idx < len; ++idx) {
41 hashState = kMagicNum * hashState + str[idx];
42 }
43
44 // The final scrambling helps with short keys that vary only on the high order bits.
45 // Low order bits are not always well distributed so shift them to the high end, where they'll
46 // form part of the 14-bit tag.
47 return Rotr64(kMagicNum * hashState, 6);
48 }
49
50 static constexpr inline bool IsPowerOfTwo(uint64_t x) {
51 return (x > 0) && ((x & (x - 1)) == 0);
52 }
53};
54
55}
56} // namespace FASTER::core
57