xref: /freebsd/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_hash.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- sanitizer_common.h --------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements a simple hash function.
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #ifndef SANITIZER_HASH_H
130b57cec5SDimitry Andric #define SANITIZER_HASH_H
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "sanitizer_internal_defs.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric namespace __sanitizer {
180b57cec5SDimitry Andric class MurMur2HashBuilder {
190b57cec5SDimitry Andric   static const u32 m = 0x5bd1e995;
200b57cec5SDimitry Andric   static const u32 seed = 0x9747b28c;
210b57cec5SDimitry Andric   static const u32 r = 24;
220b57cec5SDimitry Andric   u32 h;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric  public:
250b57cec5SDimitry Andric   explicit MurMur2HashBuilder(u32 init = 0) { h = seed ^ init; }
add(u32 k)260b57cec5SDimitry Andric   void add(u32 k) {
270b57cec5SDimitry Andric     k *= m;
280b57cec5SDimitry Andric     k ^= k >> r;
290b57cec5SDimitry Andric     k *= m;
300b57cec5SDimitry Andric     h *= m;
310b57cec5SDimitry Andric     h ^= k;
320b57cec5SDimitry Andric   }
get()330b57cec5SDimitry Andric   u32 get() {
340b57cec5SDimitry Andric     u32 x = h;
350b57cec5SDimitry Andric     x ^= x >> 13;
360b57cec5SDimitry Andric     x *= m;
370b57cec5SDimitry Andric     x ^= x >> 15;
380b57cec5SDimitry Andric     return x;
390b57cec5SDimitry Andric   }
400b57cec5SDimitry Andric };
41*349cc55cSDimitry Andric 
42*349cc55cSDimitry Andric class MurMur2Hash64Builder {
43*349cc55cSDimitry Andric   static const u64 m = 0xc6a4a7935bd1e995ull;
44*349cc55cSDimitry Andric   static const u64 seed = 0x9747b28c9747b28cull;
45*349cc55cSDimitry Andric   static const u64 r = 47;
46*349cc55cSDimitry Andric   u64 h;
47*349cc55cSDimitry Andric 
48*349cc55cSDimitry Andric  public:
49*349cc55cSDimitry Andric   explicit MurMur2Hash64Builder(u64 init = 0) { h = seed ^ (init * m); }
add(u64 k)50*349cc55cSDimitry Andric   void add(u64 k) {
51*349cc55cSDimitry Andric     k *= m;
52*349cc55cSDimitry Andric     k ^= k >> r;
53*349cc55cSDimitry Andric     k *= m;
54*349cc55cSDimitry Andric     h ^= k;
55*349cc55cSDimitry Andric     h *= m;
56*349cc55cSDimitry Andric   }
get()57*349cc55cSDimitry Andric   u64 get() {
58*349cc55cSDimitry Andric     u64 x = h;
59*349cc55cSDimitry Andric     x ^= x >> r;
60*349cc55cSDimitry Andric     x *= m;
61*349cc55cSDimitry Andric     x ^= x >> r;
62*349cc55cSDimitry Andric     return x;
63*349cc55cSDimitry Andric   }
64*349cc55cSDimitry Andric };
650b57cec5SDimitry Andric }  // namespace __sanitizer
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric #endif  // SANITIZER_HASH_H
68