Blender  V2.93
BLI_probing_strategies.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
56 #include "BLI_sys_types.h"
57 
58 namespace blender {
59 
66  private:
67  uint64_t hash_;
68 
69  public:
71  {
72  }
73 
74  void next()
75  {
76  hash_++;
77  }
78 
79  uint64_t get() const
80  {
81  return hash_;
82  }
83 
85  {
86  return UINT32_MAX;
87  }
88 };
89 
102  private:
103  uint64_t original_hash_;
104  uint64_t current_hash_;
105  uint64_t iteration_;
106 
107  public:
109  : original_hash_(hash), current_hash_(hash), iteration_(1)
110  {
111  }
112 
113  void next()
114  {
115  current_hash_ = original_hash_ + ((iteration_ * iteration_ + iteration_) >> 1);
116  iteration_++;
117  }
118 
119  uint64_t get() const
120  {
121  return current_hash_;
122  }
123 
125  {
126  return 1;
127  }
128 };
129 
140 template<uint64_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
141  private:
142  uint64_t hash_;
143  uint64_t perturb_;
144 
145  public:
146  PythonProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
147  {
148  if (PreShuffle) {
149  this->next();
150  }
151  }
152 
153  void next()
154  {
155  perturb_ >>= 5;
156  hash_ = 5 * hash_ + 1 + perturb_;
157  }
158 
159  uint64_t get() const
160  {
161  return hash_;
162  }
163 
165  {
166  return LinearSteps;
167  }
168 };
169 
175 template<uint64_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
176  private:
177  uint64_t hash_;
178  uint64_t perturb_;
179 
180  public:
181  ShuffleProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
182  {
183  if (PreShuffle) {
184  this->next();
185  }
186  }
187 
188  void next()
189  {
190  if (perturb_ != 0) {
191  perturb_ >>= 10;
192  hash_ = ((hash_ >> 16) ^ hash_) * 0x45d9f3b + perturb_;
193  }
194  else {
195  hash_ = 5 * hash_ + 1;
196  }
197  }
198 
199  uint64_t get() const
200  {
201  return hash_;
202  }
203 
205  {
206  return LinearSteps;
207  }
208 };
209 
214 
215 /* Turning off clang format here, because otherwise it will mess up the alignment between the
216  * macros. */
217 // clang-format off
218 
232 #define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX) \
233  PROBING_STRATEGY probing_strategy(HASH); \
234  do { \
235  int64_t linear_offset = 0; \
236  uint64_t current_hash = probing_strategy.get(); \
237  do { \
238  int64_t R_SLOT_INDEX = static_cast<int64_t>((current_hash + static_cast<uint64_t>(linear_offset)) & MASK);
239 
240 #define SLOT_PROBING_END() \
241  } while (++linear_offset < probing_strategy.linear_steps()); \
242  probing_strategy.next(); \
243  } while (true)
244 
245 // clang-format on
246 
247 } // namespace blender
LinearProbingStrategy(const uint64_t hash)
#define hash
Definition: noise.c:169
__int64 int64_t
Definition: stdint.h:92
#define UINT32_MAX
Definition: stdint.h:145
unsigned __int64 uint64_t
Definition: stdint.h:93