blob: eb1365df0e1520e4ea2aa57a4132248d52ffa964 [file] [log] [blame]
Ryan Keane07dc4022020-04-01 10:16:10 -07001// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UTIL_HASHING_H_
6#define UTIL_HASHING_H_
7
mark a. foltzf7b87d22021-10-14 15:34:44 -07008#include <utility>
9#include <vector>
10
Ryan Keane07dc4022020-04-01 10:16:10 -070011namespace openscreen {
12
mark a. foltzf7b87d22021-10-14 15:34:44 -070013// This value is taken from absl::Hash implementation.
14constexpr uint64_t kDefaultSeed = UINT64_C(0xc3a5c85c97cb3127);
15
Ryan Keane07dc4022020-04-01 10:16:10 -070016// Computes the aggregate hash of the provided hashable objects.
17// Seed must initially use a large prime between 2^63 and 2^64 as a starting
18// value, or the result of a previous call to this function.
19template <typename... T>
mark a. foltzf7b87d22021-10-14 15:34:44 -070020uint64_t ComputeAggregateHash(uint64_t original_seed, const T&... objs) {
21 auto hash_combiner = [](uint64_t current_seed,
22 uint64_t hash_value) -> uint64_t {
Ryan Keane07dc4022020-04-01 10:16:10 -070023 static const uint64_t kMultiplier = UINT64_C(0x9ddfea08eb382d69);
mark a. foltzf7b87d22021-10-14 15:34:44 -070024 uint64_t a = (hash_value ^ current_seed) * kMultiplier;
Ryan Keane07dc4022020-04-01 10:16:10 -070025 a ^= (a >> 47);
mark a. foltzf7b87d22021-10-14 15:34:44 -070026 uint64_t b = (current_seed ^ a) * kMultiplier;
Ryan Keane07dc4022020-04-01 10:16:10 -070027 b ^= (b >> 47);
28 b *= kMultiplier;
29 return b;
30 };
31
mark a. foltzf7b87d22021-10-14 15:34:44 -070032 uint64_t result = original_seed;
Ryan Keane07dc4022020-04-01 10:16:10 -070033 std::vector<uint64_t> hashes{std::hash<T>()(objs)...};
34 for (uint64_t hash : hashes) {
35 result = hash_combiner(result, hash);
36 }
37 return result;
38}
39
40template <typename... T>
41uint64_t ComputeAggregateHash(const T&... objs) {
42 // This value is taken from absl::Hash implementation.
43 constexpr uint64_t default_seed = UINT64_C(0xc3a5c85c97cb3127);
44 return ComputeAggregateHash(default_seed, objs...);
45}
46
47struct PairHash {
48 template <typename TFirst, typename TSecond>
49 size_t operator()(const std::pair<TFirst, TSecond>& pair) const {
50 return ComputeAggregateHash(pair.first, pair.second);
51 }
52};
53
54} // namespace openscreen
55
56#endif // UTIL_HASHING_H_