IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
murmur2.hxx
Go to the documentation of this file.
1
3
8/*
9 * Copyright (c) 2018 Nathan Lewis <linux.robotdude@gmail.com>
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of mosquitto nor the names of its
21 * contributors may be used to endorse or promote products derived from
22 * this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#pragma once
38#include <ice/types.hxx>
39#include <string_view>
40
42{
43
45 {
47 };
48
49 constexpr auto cexpr_murmur2_x64_64(std::u8string_view key, ice::u64 seed) noexcept -> mm2_x64_64;
50
51 constexpr auto cexpr_murmur2_x64_64(std::string_view key, ice::u64 seed) noexcept -> mm2_x64_64;
52
53 // Murmur hash constants
54 constexpr ice::u64 m = 0xc6a4a7935bd1e995;
55 constexpr ice::u32 r = 47;
56
57 constexpr auto crotate(ice::u64 a) noexcept -> ice::u64
58 {
59 return a ^ (a >> r);
60 }
61
62 template<typename CharType>
63 constexpr auto cfinalize_h(CharType const* data, size_t key, ice::u64 h) noexcept -> ice::u64
64 {
65 return (key != 0) ? cfinalize_h(data, key - 1, (h ^ (ice::u64(data[key - 1]) << (8 * (key - 1))))) : h* m;
66 }
67
68 template<typename CharType>
69 constexpr auto cfinalize(CharType const* data, size_t len, ice::u64 h) noexcept -> ice::u64
70 {
71 return (len & 7) ? crotate(crotate(cfinalize_h<CharType>(data, len & 7, h)) * m)
72 : crotate(crotate(h) * m);
73 }
74
75 // reinterpret cast is illegal (static is fine) so we have to manually load 64 bit chuncks of string instead
76 // of casting char* to ice::u64*
77 //
78 // TODO - this only works on little endian machines .... fuuuu
79 template<typename CharType>
80 constexpr auto cblock(CharType const* data, size_t offset = 0) noexcept -> ice::u64
81 {
82 return (offset == 7) ? ice::u64(data[offset]) << (8 * offset)
83 : (ice::u64(data[offset]) << (8 * offset)) | cblock<CharType>(data, offset + 1);
84 }
85
86 // Mixing function for the hash function
87 template<typename CharType>
88 constexpr auto cmix_h(CharType const* data, ice::u64 h, size_t offset) noexcept -> ice::u64
89 {
90 return (h ^ (crotate(cblock<CharType>(data + offset) * m) * m)) * m;
91 }
92
93 // Control function for the mixing
94 template<typename CharType>
95 constexpr auto cmix(CharType const* data, size_t len, ice::u64 h, size_t offset = 0) noexcept -> ice::u64
96 {
97 return (offset == (len & ~size_t(7))) ? cfinalize<CharType>(data + offset, len, h)
98 : cmix<CharType>(data, len, cmix_h<CharType>(data, h, offset), offset + 8);
99 }
100
101 constexpr auto cexpr_murmur2_x64_64(std::string_view key, ice::u64 seed) noexcept -> mm2_x64_64
102 {
103 ice::u64 const h = cmix<char>(key.data(), key.length(), seed ^ (key.length() * m));
104 return mm2_x64_64{ .h = { h } };
105 }
106
107 constexpr auto cexpr_murmur2_x64_64(std::u8string_view key, ice::u64 seed) noexcept -> mm2_x64_64
108 {
109 ice::u64 const h = cmix<ice::utf8>(key.data(), key.length(), seed ^ (key.length() * m));
110 return mm2_x64_64{ .h = { h } };
111 }
112
113} // namespace ice::detail::murmur2_hash
Definition span.hxx:129
Definition murmur2.hxx:42
constexpr auto cmix(CharType const *data, size_t len, ice::u64 h, size_t offset=0) noexcept -> ice::u64
Definition murmur2.hxx:95
constexpr auto cfinalize_h(CharType const *data, size_t key, ice::u64 h) noexcept -> ice::u64
Definition murmur2.hxx:63
constexpr auto cfinalize(CharType const *data, size_t len, ice::u64 h) noexcept -> ice::u64
Definition murmur2.hxx:69
constexpr ice::u64 m
Definition murmur2.hxx:54
constexpr auto cblock(CharType const *data, size_t offset=0) noexcept -> ice::u64
Definition murmur2.hxx:80
constexpr auto cmix_h(CharType const *data, ice::u64 h, size_t offset) noexcept -> ice::u64
Definition murmur2.hxx:88
constexpr auto cexpr_murmur2_x64_64(std::u8string_view key, ice::u64 seed) noexcept -> mm2_x64_64
Definition murmur2.hxx:107
constexpr auto crotate(ice::u64 a) noexcept -> ice::u64
Definition murmur2.hxx:57
constexpr ice::u32 r
Definition murmur2.hxx:55
SPDX-License-Identifier: MIT.
Definition array.hxx:12
std::uint64_t u64
Definition types.hxx:27
std::uint32_t u32
Definition types.hxx:26
Definition murmur2.hxx:45
ice::u64 h[1]
Definition murmur2.hxx:46