FastLED 3.9.15
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1
2#pragma once
3
4#include "fl/str.h"
5#include "fl/template_magic.h"
6#include <stdint.h>
7#include <string.h>
8
9namespace fl {
10
11template <typename T> struct vec2;
12
13//-----------------------------------------------------------------------------
14// MurmurHash3 x86 32-bit
15//-----------------------------------------------------------------------------
16// Based on the public‐domain implementation by Austin Appleby:
17// https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
18static inline uint32_t MurmurHash3_x86_32(const void *key, size_t len,
19 uint32_t seed = 0) {
20#pragma GCC diagnostic push
21#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
22
23 const uint8_t *data = static_cast<const uint8_t *>(key);
24 const int nblocks = int(len / 4);
25
26 uint32_t h1 = seed;
27 const uint32_t c1 = 0xcc9e2d51;
28 const uint32_t c2 = 0x1b873593;
29
30 // body
31 const uint32_t *blocks = reinterpret_cast<const uint32_t *>(data);
32 for (int i = 0; i < nblocks; ++i) {
33 uint32_t k1 = blocks[i];
34 k1 *= c1;
35 k1 = (k1 << 15) | (k1 >> 17);
36 k1 *= c2;
37
38 h1 ^= k1;
39 h1 = (h1 << 13) | (h1 >> 19);
40 h1 = h1 * 5 + 0xe6546b64;
41 }
42
43 // tail
44 const uint8_t *tail = data + (nblocks * 4);
45 uint32_t k1 = 0;
46 switch (len & 3) {
47 case 3:
48 k1 ^= uint32_t(tail[2]) << 16;
49 case 2:
50 k1 ^= uint32_t(tail[1]) << 8;
51 case 1:
52 k1 ^= uint32_t(tail[0]);
53 k1 *= c1;
54 k1 = (k1 << 15) | (k1 >> 17);
55 k1 *= c2;
56 h1 ^= k1;
57 }
58
59 // finalization
60 h1 ^= uint32_t(len);
61 // fmix32
62 h1 ^= h1 >> 16;
63 h1 *= 0x85ebca6b;
64 h1 ^= h1 >> 13;
65 h1 *= 0xc2b2ae35;
66 h1 ^= h1 >> 16;
67
68 return h1;
69
70#pragma GCC diagnostic pop
71}
72
73//-----------------------------------------------------------------------------
74// Fast, cheap 32-bit integer hash (Thomas Wang)
75//-----------------------------------------------------------------------------
76static inline uint32_t fast_hash32(uint32_t x) noexcept {
77 x = (x ^ 61u) ^ (x >> 16);
78 x = x + (x << 3);
79 x = x ^ (x >> 4);
80 x = x * 0x27d4eb2dU;
81 x = x ^ (x >> 15);
82 return x;
83}
84
85// 3) Handy two-word hasher
86static inline uint32_t hash_pair(uint32_t a, uint32_t b,
87 uint32_t seed = 0) noexcept {
88 // mix in 'a', then mix in 'b'
89 uint32_t h = fast_hash32(seed ^ a);
90 return fast_hash32(h ^ b);
91}
92
93//-----------------------------------------------------------------------------
94// Functor for hashing arbitrary byte‐ranges to a 32‐bit value
95//-----------------------------------------------------------------------------
96// https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
97template <typename T> struct Hash {
98 static_assert(fl::is_pod<T>::value,
99 "fl::Hash<T> only supports POD types (integrals, floats, "
100 "etc.), you need to define your own hash.");
101 uint32_t operator()(const T &key) const noexcept {
102 return MurmurHash3_x86_32(&key, sizeof(T));
103 }
104};
105
106template <typename T> struct FastHash {
107 static_assert(fl::is_pod<T>::value,
108 "fl::FastHash<T> only supports POD types (integrals, floats, "
109 "etc.), you need to define your own hash.");
110 uint32_t operator()(const T &key) const noexcept {
111 return fast_hash32(key);
112 }
113};
114
115template <typename T> struct FastHash<vec2<T>> {
116 uint32_t operator()(const vec2<T> &key) const noexcept {
117 if (sizeof(T) == sizeof(uint8_t)) {
118 uint32_t x = static_cast<uint32_t>(key.x) +
119 (static_cast<uint32_t>(key.y) << 8);
120 return fast_hash32(x);
121 }
122 if (sizeof(T) == sizeof(uint16_t)) {
123 uint32_t x = static_cast<uint32_t>(key.x) +
124 (static_cast<uint32_t>(key.y) << 16);
125 return fast_hash32(x);
126 }
127 if (sizeof(T) == sizeof(uint32_t)) {
128 return hash_pair(key.x, key.y);
129 }
130 return MurmurHash3_x86_32(&key, sizeof(T));
131 }
132};
133
134template <typename T> struct Hash<T *> {
135 uint32_t operator()(const T *key) const noexcept {
136 return fast_hash32(key, sizeof(T *));
137 }
138};
139
140template <typename T> struct Hash<vec2<T>> {
141 uint32_t operator()(const vec2<T> &key) const noexcept {
142#ifndef __clang__
143#pragma GCC diagnostic push
144#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
145#endif
146 T packed[2];
147 memset(packed, 0, sizeof(packed));
148 packed[0] = key.x;
149 packed[1] = key.y; // Protect against alignment issues
150 const void *p = &packed[0];
151 return MurmurHash3_x86_32(p, sizeof(packed));
152#ifndef __clang__
153#pragma GCC diagnostic pop
154#endif
155 }
156};
157
158template <typename T> struct Hash<Ptr<T>> {
159 uint32_t operator()(const T &key) const noexcept {
160 auto hasher = Hash<T *>();
161 return hasher(key.get());
162 }
163};
164
165#define FASTLED_DEFINE_FAST_HASH(T) \
166 template <> struct Hash<T> { \
167 uint32_t operator()(const int &key) const noexcept { \
168 return fast_hash32(key); \
169 } \
170 };
171
181// FASTLED_DEFINE_FAST_HASH(int)
182
183//-----------------------------------------------------------------------------
184// Convenience for std::string → uint32_t
185//----------------------------------------------------------------------------
186template <> struct Hash<fl::Str> {
187 uint32_t operator()(const fl::Str &key) const noexcept {
188 return MurmurHash3_x86_32(key.data(), key.size());
189 }
190};
191
192} // namespace fl
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:82
Definition ptr.h:118
const char * data() const
Definition str.h:572
Definition str.h:388
size_t size() const
Definition str.h:270
#define FASTLED_DEFINE_FAST_HASH(T)
Definition hash.h:165
static uint32_t MurmurHash3_x86_32(const void *key, size_t len, uint32_t seed=0)
Definition hash.h:18
static uint32_t fast_hash32(uint32_t x) noexcept
Definition hash.h:76
static uint32_t hash_pair(uint32_t a, uint32_t b, uint32_t seed=0) noexcept
Definition hash.h:86
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
static FASTLED_NAMESPACE_BEGIN uint8_t const p[]
Definition noise.cpp:30
uint32_t operator()(const vec2< T > &key) const noexcept
Definition hash.h:116
uint32_t operator()(const T &key) const noexcept
Definition hash.h:110
uint32_t operator()(const T &key) const noexcept
Definition hash.h:159
uint32_t operator()(const T *key) const noexcept
Definition hash.h:135
uint32_t operator()(const vec2< T > &key) const noexcept
Definition hash.h:141
uint32_t operator()(const T &key) const noexcept
Definition hash.h:101
static constexpr bool value