1 //===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines utilities for computing hash values for various data types.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_ADT_HASHING_H
15 #define LLVM_ADT_HASHING_H
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/AlignOf.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/DataTypes.h"
25 /// Class to compute a hash value from multiple data fields of arbitrary
26 /// types. Note that if you are hashing a single data type, such as a
27 /// string, it may be cheaper to use a hash algorithm that is tailored
28 /// for that specific data type.
31 /// Hash.add(someValue);
32 /// Hash.add(someOtherValue);
33 /// return Hash.finish();
34 /// Adapted from MurmurHash2 by Austin Appleby
43 GeneralHash(unsigned Seed = 0) : Hash(Seed), Count(0) {}
45 /// Add a pointer value.
46 /// Note: this adds pointers to the hash using sizes and endianness that
47 /// depend on the host. It doesn't matter however, because hashing on
48 /// pointer values is inherently unstable.
50 GeneralHash& add(const T *PtrVal) {
51 addBits(&PtrVal, &PtrVal + 1);
55 /// Add an ArrayRef of arbitrary data.
57 GeneralHash& add(ArrayRef<T> ArrayVal) {
58 addBits(ArrayVal.begin(), ArrayVal.end());
63 GeneralHash& add(StringRef StrVal) {
64 addBits(StrVal.begin(), StrVal.end());
68 /// Add an signed 32-bit integer.
69 GeneralHash& add(int32_t Data) {
70 addInt(uint32_t(Data));
74 /// Add an unsigned 32-bit integer.
75 GeneralHash& add(uint32_t Data) {
80 /// Add an signed 64-bit integer.
81 GeneralHash& add(int64_t Data) {
82 addInt(uint64_t(Data));
86 /// Add an unsigned 64-bit integer.
87 GeneralHash& add(uint64_t Data) {
93 GeneralHash& add(float Data) {
103 GeneralHash& add(double Data) {
105 double D; uint64_t I;
112 // Do a few final mixes of the hash to ensure the last few
113 // bytes are well-incorporated.
123 void mix(uint32_t Data) {
132 // Add a single uint32 value
133 void addInt(uint32_t Val) {
137 // Add a uint64 value
138 void addInt(uint64_t Val) {
139 mix(uint32_t(Val >> 32));
143 template<typename T, bool isAligned>
145 static void add(GeneralHash &Hash, const T *I, const T *E) {
147 reinterpret_cast<const uint8_t *>(I),
148 reinterpret_cast<const uint8_t *>(E));
153 struct addBitsImpl<T, true> {
154 static void add(GeneralHash &Hash, const T *I, const T *E) {
156 reinterpret_cast<const uint32_t *>(I),
157 reinterpret_cast<const uint32_t *>(E));
161 // Add a range of bits from I to E.
163 void addBits(const T *I, const T *E) {
164 addBitsImpl<T, AlignOf<T>::Alignment_GreaterEqual_4Bytes>::add(*this, I, E);
167 // Add a range of uint32s
168 void addAligned(const uint32_t *I, const uint32_t *E) {
174 // Add a possibly unaligned sequence of bytes.
175 void addUnaligned(const uint8_t *I, const uint8_t *E);
178 } // end namespace llvm