Turi Create  4.0
hash_value.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_HASH_VALUE_H_
7 #define TURI_HASH_VALUE_H_
8 
9 #include <core/util/cityhash_tc.hpp>
10 #include <core/util/bitops.hpp>
11 #include <core/storage/serialization/serialization_includes.hpp>
12 
13 namespace turi {
14 /**
15  * Defines a Weak version of Token class with a fixed, constant hash
16  * value. Hashes are calculated using the cityhash_gl hash
17  * functions. It is designed as a robust key for hash tables. The
18  * difference between this class and the regular Token class is that
19  * this one only stores the hash value, making it better suited for
20  * querying over network connections.
21  *
22  */
23 class hash_value : public turi::IS_POD_TYPE {
24  public:
25  /**
26  * Creates an empty WeakToken object with the 0 hash.
27  */
29  : h_128(0)
30  {}
31 
32  /// Redirect to the appropriate hash function.
33  template <typename... Args>
34  inline hash_value(Args... args)
35  : h_128(hash128(args...))
36  {}
37 
38  /// Copy constructor
39  hash_value(const hash_value& t) : h_128(t.h_128) {}
40  hash_value(hash_value&& t) : h_128(t.h_128) {}
41  hash_value& operator=(const hash_value& t) { h_128 = t.h_128; return *this; }
42 
43  /// Explicit constructor from a hash value output
44  hash_value(uint128_t h) : h_128(h) {}
45 
46 
47  inline bool operator==(const hash_value& t) const { return t.hash() == hash(); }
48 
49  inline bool operator<(const hash_value& t) const { return t.hash() < hash(); }
50 
51  /// Returns the 128 bit hash value of the token.
52  uint128_t hash() const { return h_128; }
53 
54  /// Returns the top number of bits in the hash
55  inline size_t n_bit_index(size_t n_bits) const {
56  // Need to mix the bits a bit, since the first hash may be just an
57  // integer. multiply by a couple of random primes and xor; good
58  // enough for this.
59  uint64_t v = (h_2_64.first * 0x7e952a7b972f486fULL) ^ (h_2_64.second * 0xdeb2a42e44aa4c17ULL);
60  return v >> (bitsizeof(uint64_t) - n_bits);
61  }
62 
63  /// Serialization
64  void save(oarchive &oarc) const { oarc << h_128; }
65  void load(iarchive &iarc) { iarc >> h_128; }
66 
67  private:
68  union {
69  uint128_t h_128;
70  std::pair<uint64_t, uint64_t> h_2_64;
71  };
72 };
73 
74 }
75 
76 namespace std {
77 
78 #ifdef __clang__
79 #pragma clang diagnostic push
80 #pragma clang diagnostic ignored "-Wmismatched-tags"
81 #endif
82 
83 template <> struct hash<turi::hash_value> {
84  size_t operator()(const turi::hash_value& t) const {
85  return size_t(t.hash());
86  }
87 };
88 
89 #ifdef __clang__
90 #pragma clang diagnostic pop
91 #endif
92 
93 }
94 
95 #endif
static uint128_t hash128(const char *s, size_t len)
The serialization input archive object which, provided with a reference to an istream, will read from the istream, providing deserialization capabilities.
Definition: iarchive.hpp:60
hash_value(uint128_t h)
Explicit constructor from a hash value output.
Definition: hash_value.hpp:44
STL namespace.
size_t n_bit_index(size_t n_bits) const
Returns the top number of bits in the hash.
Definition: hash_value.hpp:55
hash_value(Args... args)
Redirect to the appropriate hash function.
Definition: hash_value.hpp:34
Inheriting from this type will force the serializer to treat the derived type as a POD type...
Definition: is_pod.hpp:16
hash_value(const hash_value &t)
Copy constructor.
Definition: hash_value.hpp:39
The serialization output archive object which, provided with a reference to an ostream, will write to the ostream, providing serialization capabilities.
Definition: oarchive.hpp:80
void save(oarchive &oarc) const
Serialization.
Definition: hash_value.hpp:64
uint128_t hash() const
Returns the 128 bit hash value of the token.
Definition: hash_value.hpp:52