/src/WasmEdge/include/common/hash.h
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: 2019-2022 Second State INC |
3 | | |
4 | | //===-- wasmedge/common/hash.h - Fast hash function -----------------------===// |
5 | | // |
6 | | // Part of the WasmEdge Project. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// |
10 | | /// \file |
11 | | /// This file contains the functions about hashing data. |
12 | | /// Currently using rapidhash. |
13 | | /// |
14 | | //===----------------------------------------------------------------------===// |
15 | | #pragma once |
16 | | |
17 | | #include "common/defines.h" |
18 | | #include "common/endian.h" |
19 | | #include "common/errcode.h" |
20 | | #include "common/int128.h" |
21 | | #include "common/span.h" |
22 | | #include "common/variant.h" |
23 | | |
24 | | #include <array> |
25 | | #include <cstdint> |
26 | | #include <random> |
27 | | #include <string_view> |
28 | | #include <type_traits> |
29 | | |
30 | | namespace WasmEdge::Hash { |
31 | 352k | inline constexpr void rapidMum(uint64_t &A, uint64_t &B) noexcept { |
32 | 352k | uint128_t R = A; |
33 | 352k | R *= B; |
34 | 352k | A = static_cast<uint64_t>(R); |
35 | 352k | B = static_cast<uint64_t>(R >> 64); |
36 | 352k | } |
37 | 338k | inline constexpr uint64_t rapidMix(uint64_t A, uint64_t B) noexcept { |
38 | 338k | rapidMum(A, B); |
39 | 338k | return A ^ B; |
40 | 338k | } |
41 | | |
42 | | struct RandomEngine { |
43 | | using result_type = uint64_t; |
44 | 4 | RandomEngine() noexcept { |
45 | 4 | std::random_device RD; |
46 | 4 | std::uniform_int_distribution<uint64_t> Dist(0, UINT64_MAX); |
47 | 4 | Seed = Dist(RD); |
48 | 4 | } |
49 | 0 | RandomEngine(result_type S) noexcept : Seed(S) {} |
50 | 0 | static inline constexpr result_type min() noexcept { return 0; } |
51 | 0 | static inline constexpr result_type max() noexcept { return UINT64_MAX; } |
52 | 303k | result_type operator()() noexcept { |
53 | 303k | Seed += 0x2d358dccaa6c78a5ull; |
54 | 303k | return rapidMix(Seed, Seed ^ 0x8bb84b93962eacc9ull); |
55 | 303k | } |
56 | | result_type Seed; |
57 | | }; |
58 | | |
59 | | static inline thread_local RandomEngine RandEngine; |
60 | | |
61 | | struct Hash { |
62 | | WASMEDGE_EXPORT static uint64_t |
63 | | rapidHash(Span<const std::byte> Data) noexcept; |
64 | | |
65 | | template <typename CharT> |
66 | | inline uint64_t operator()(const CharT *Str) const noexcept { |
67 | | std::basic_string_view<CharT> View(Str); |
68 | | Span<const CharT> S(View.data(), View.size()); |
69 | | return rapidHash(cxx20::as_bytes(S)); |
70 | | } |
71 | | template <typename CharT> |
72 | | inline uint64_t |
73 | 0 | operator()(const std::basic_string<CharT> &Str) const noexcept { |
74 | 0 | Span<const CharT> S(Str.data(), Str.size()); |
75 | 0 | return rapidHash(cxx20::as_bytes(S)); |
76 | 0 | } |
77 | | template <typename CharT> |
78 | | inline uint64_t |
79 | 14.5k | operator()(const std::basic_string_view<CharT> &Str) const noexcept { |
80 | 14.5k | Span<const CharT> S(Str.data(), Str.size()); |
81 | 14.5k | return rapidHash(cxx20::as_bytes(S)); |
82 | 14.5k | } |
83 | | template <typename T, std::enable_if_t<std::is_integral_v<std::remove_cv_t< |
84 | | std::remove_reference_t<T>>>> * = nullptr> |
85 | | inline uint64_t operator()(const T &Value) const noexcept { |
86 | | RandomEngine E(Value); |
87 | | return E(); |
88 | | } |
89 | | }; |
90 | | |
91 | | } // namespace WasmEdge::Hash |