Blender V5.0
BLI_probing_strategies.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
43
44#include <limits>
45
46#include "BLI_sys_types.h"
47
48namespace blender {
49
56 private:
57 uint64_t hash_;
58
59 public:
61
62 void next()
63 {
64 hash_++;
65 }
66
67 uint64_t get() const
68 {
69 return hash_;
70 }
71
73 {
74 return std::numeric_limits<int64_t>::max();
75 }
76};
77
90 private:
91 uint64_t original_hash_;
92 uint64_t current_hash_;
93 uint64_t iteration_ = 1;
94
95 public:
96 QuadraticProbingStrategy(const uint64_t hash) : original_hash_(hash), current_hash_(hash) {}
97
98 void next()
99 {
100 current_hash_ = original_hash_ + ((iteration_ * iteration_ + iteration_) >> 1);
101 iteration_++;
102 }
103
104 uint64_t get() const
105 {
106 return current_hash_;
107 }
108
110 {
111 return 1;
112 }
113};
114
125template<uint64_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
126 private:
127 uint64_t hash_;
128 uint64_t perturb_;
129
130 public:
131 PythonProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
132 {
133 if (PreShuffle) {
134 this->next();
135 }
136 }
137
138 void next()
139 {
140 perturb_ >>= 5;
141 hash_ = 5 * hash_ + 1 + perturb_;
142 }
143
144 uint64_t get() const
145 {
146 return hash_;
147 }
148
150 {
151 return LinearSteps;
152 }
153};
154
160template<uint64_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
161 private:
162 uint64_t hash_;
163 uint64_t perturb_;
164
165 public:
166 ShuffleProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
167 {
168 if (PreShuffle) {
169 this->next();
170 }
171 }
172
173 void next()
174 {
175 if (perturb_ != 0) {
176 perturb_ >>= 10;
177 hash_ = ((hash_ >> 16) ^ hash_) * 0x45d9f3b + perturb_;
178 }
179 else {
180 hash_ = 5 * hash_ + 1;
181 }
182 }
183
184 uint64_t get() const
185 {
186 return hash_;
187 }
188
190 {
191 return LinearSteps;
192 }
193};
194
199
200/* Turning off clang format here, because otherwise it will mess up the alignment between the
201 * macros. */
202// clang-format off
203
217#define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX) \
218 PROBING_STRATEGY probing_strategy(HASH); \
219 do { \
220 int64_t linear_offset = 0; \
221 uint64_t current_hash = probing_strategy.get(); \
222 do { \
223 int64_t R_SLOT_INDEX = int64_t((current_hash + uint64_t(linear_offset)) & MASK);
224
225#define SLOT_PROBING_END() \
226 } while (++linear_offset < probing_strategy.linear_steps()); \
227 probing_strategy.next(); \
228 } while (true)
229
230// clang-format on
231
232} // namespace blender
long long int int64_t
unsigned long long int uint64_t
PythonProbingStrategy<> DefaultProbingStrategy
#define hash
Definition noise_c.cc:154