YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/gutil/hash/builtin_type_hash.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2011 Google Inc. All Rights Reserved.
2
//
3
// The following only applies to changes made to this file as part of YugaByte development.
4
//
5
// Portions Copyright (c) YugaByte, Inc.
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8
// in compliance with the License.  You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software distributed under the License
13
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14
// or implied.  See the License for the specific language governing permissions and limitations
15
// under the License.
16
//
17
// Hash functions for C++ builtin types. These are all of the fundamental
18
// integral and floating point types in the language as well as pointers. This
19
// library provides a minimal set of interfaces for hashing these values.
20
21
#ifndef UTIL_HASH_BUILTIN_TYPE_HASH_H_
22
#define UTIL_HASH_BUILTIN_TYPE_HASH_H_
23
24
#include <stddef.h>
25
#include <stdint.h>
26
27
#include "yb/gutil/casts.h"
28
#include "yb/gutil/integral_types.h"
29
#include "yb/gutil/macros.h"
30
#include "yb/gutil/hash/jenkins_lookup2.h"
31
32
0
inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) {
33
0
  uint32 b = 0x9e3779b9UL;            // the golden ratio; an arbitrary value
34
0
  mix(num, b, c);
35
0
  return c;
36
0
}
37
38
0
inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) {
39
0
  uint64 b = GG_ULONGLONG(0xe08c1d668b756f82);   // more of the golden ratio
40
0
  mix(num, b, c);
41
0
  return c;
42
0
}
43
44
// This function hashes pointer sized items and returns a 32b hash,
45
// convenienty hiding the fact that pointers may be 32b or 64b,
46
// depending on the architecture.
47
0
inline uint32 Hash32PointerWithSeed(const void* p, uint32 seed) {
48
0
  uintptr_t pvalue = reinterpret_cast<uintptr_t>(p);
49
0
  uint32 h = seed;
50
0
  // Hash the pointer 32b at a time.
51
0
  for (size_t i = 0; i < sizeof(pvalue); i += 4) {
52
0
    h = Hash32NumWithSeed(static_cast<uint32>(pvalue >> (i*8)), h);
53
0
  }
54
0
  return h;
55
0
}
56
57
// ----------------------------------------------------------------------
58
// Hash64FloatWithSeed
59
// Hash64DoubleWithSeed
60
//   Functions for computing a hash value of floating-point numbers.
61
//   On systems where float and double comply with IEEE 754, these hashes
62
//   guarantee that if a == b, Hash64FloatWithSeed(a, c) ==
63
//   Hash64FloatWithSeed(b, c). Note that NaN does not compare equal to
64
//   itself, so two NaN inputs will not necessarily hash to the same value.
65
//
66
//   It is often a mistake to compare floating-point values for equality,
67
//   since floating-point computations do not produce exact values, due to
68
//   rounding. If equality comparison doesn't make sense in your situation,
69
//   hashing almost certainly doesn't make sense either.
70
//
71
//   Not guaranteed to return the same value in different builds, or to
72
//   avoid any reserved values.
73
// ----------------------------------------------------------------------
74
0
inline uint64 Hash64FloatWithSeed(float num, uint64 seed) {
75
0
  // +0 and -0 are the only floating point numbers which compare equal but
76
0
  // have distinct bitwise representations in IEEE 754. To work around this,
77
0
  // we force 0 to be +0.
78
0
  if (num == 0) {
79
0
    num = 0;
80
0
  }
81
0
  COMPILE_ASSERT(sizeof(float) == sizeof(uint32), float_has_wrong_size);
82
0
83
0
  const uint64 kMul = 0xc6a4a7935bd1e995ULL;
84
0
85
0
  uint64 a = (bit_cast<uint32>(num) + seed) * kMul;
86
0
  a ^= (a >> 47);
87
0
  a *= kMul;
88
0
  a ^= (a >> 47);
89
0
  a *= kMul;
90
0
  return a;
91
0
}
92
93
0
inline uint64 Hash64DoubleWithSeed(double num, uint64 seed) {
94
0
  if (num == 0) {
95
0
    num = 0;
96
0
  }
97
0
  COMPILE_ASSERT(sizeof(double) == sizeof(uint64), double_has_wrong_size);
98
0
99
0
  const uint64 kMul = 0xc6a4a7935bd1e995ULL;
100
0
101
0
  uint64 a = (bit_cast<uint64>(num) + seed) * kMul;
102
0
  a ^= (a >> 47);
103
0
  a *= kMul;
104
0
  a ^= (a >> 47);
105
0
  a *= kMul;
106
0
  return a;
107
0
}
108
109
#endif  // UTIL_HASH_BUILTIN_TYPE_HASH_H_