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