Tactics: Western Philosophers Vs. Musicians  0.12
A turn-based tactical game combining rules and gameplay elements inspired by Final Fantasy Tactics and the Mayfair Exponential Game System. Unlike most games of this type, motion is in full, grid-less 3D.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UHash.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2012 Dylan Blair
3 //
4 // email: dblair@alumni.cs.utexas.edu
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 
21 #ifndef UHASH_H
22 #define UHASH_H
23 
24 #include "UTypes.h"
25 
26 #ifdef _DEBUG
27 #include <math.h>
28 #endif
29 #include <assert.h>
30 
31 namespace OpenSkyNet {
32  namespace Utils {
34  const uint INITIAL_TABLE_SIZE = 512;
35 
40  const uint MAX_3D_COMPONENT_KEY = 1024;
41 
44  inline uint getCompositeKey(uint x_, uint y_, uint z_) {
45  assert(MAX_3D_COMPONENT_KEY >= x_);
46  assert(MAX_3D_COMPONENT_KEY >= y_);
47  assert(MAX_3D_COMPONENT_KEY >= z_);
48  return x_ | (y_ << 10) | (z_ << 20);
49  }
50 
52  inline uint HashUIntToUInt(const uint& key_) {
53  uint hash = 0;
54 
55  hash += (key_ & 0x000000FF);
56  hash += (hash << 10);
57  hash ^= (hash >> 6);
58  hash += (key_ & 0x0000FF00);
59  hash += (hash << 10);
60  hash ^= (hash >> 6);
61  hash += (key_ & 0x00FF0000);
62  hash += (hash << 10);
63  hash ^= (hash >> 6);
64  hash += (key_ & 0xFF000000);
65  hash += (hash << 10);
66  hash ^= (hash >> 6);
67 
68  hash += (hash << 3);
69  hash ^= (hash >> 11);
70  hash += (hash << 15);
71 
72  //Here, we make the most significant bit 1 so
73  //we are assured to never have a 0 hash. In
74  //our table, we signify that a bin is unused
75  //if it has a 0 hash stored. Although
76  //assigning this bit divides the available
77  //key space in 2, we should not have a table
78  //large enough ( > 2147483648 bins) to need
79  //the full hash.
80  hash ^= 0x80000000;
81 
82  return hash;
83  }
84 
85  template<class T=uint>
88  struct TableNode {
89  uint _hash, _key;
90  T _value;
91  TableNode() : _hash(0), _key(0) {}
92  };
93  public:
94  HashTableUIntKeys(uint powerOf2InitialSize_) :
95  _load(0), _size(powerOf2InitialSize_),
96  _initSize(_size), _sizeMinusOne(_size - 1),
97  _maxLoad(static_cast<uint>(static_cast<float>(_size) * 0.75f)),
98  _isUsingDefaultValue(false),
99  _table(new TableNode[_size]) {
100 #ifdef _DEBUG
101  assert(_size < 2147483649u);
102  double logSize = log(static_cast<double>(powerOf2InitialSize_));
103  double log2 = log(2.0);
104  double logSizeBase2 = logSize / log2;
105  double logSizeBase2Truncated = static_cast<double>(static_cast<uint>(logSizeBase2));
106  assert(logSizeBase2 == logSizeBase2Truncated);
107 #endif
108  }
109 
110  HashTableUIntKeys(uint powerOf2InitialSize_, const T& defaultValue_) :
111  _load(0), _size(powerOf2InitialSize_),
112  _initSize(_size), _sizeMinusOne(_size - 1),
113  _maxLoad(static_cast<uint>(static_cast<float>(_size) * 0.75f)),
114  _isUsingDefaultValue(true), _defaultValue(defaultValue_),
115  _table(new TableNode[_size]) {
116 #ifdef _DEBUG
117  assert(_size < 2147483649u);
118  double logSize = log(static_cast<double>(powerOf2InitialSize_));
119  double log2 = log(2.0);
120  double logSizeBase2 = logSize / log2;
121  double logSizeBase2Truncated = static_cast<double>(static_cast<uint>(logSizeBase2));
122  assert(logSizeBase2 == logSizeBase2Truncated);
123 #endif
124  for (uint i = 0; i < _size; i++)
125  _table[i]._value = _defaultValue;
126  }
127 
129  delete[] _table;
130  }
131 
133  _table = 0;
134  *this = hashTable_;
135  }
136 
138  if (this == &hashTable_) return this;
139 
140  _load = hashTable_._load;
141  _size = hashTable_._size;
142  _initSize = hashTable_._initSize;
143  _sizeMinusOne = hashTable_._sizeMinusOne;
144  _maxLoad = hashTable_._maxLoad;
145  _isUsingDefaultValue = hashTable_._isUsingDefaultValue;
146  _defaultValue = hashTable_._defaultValue;
147 
148  if (_table) delete[] _table;
149  _table = new TableNode[_size];
150  for (uint i = 0; i < _size; ++i) {
151  _table[i]._hash = hashTable_[i]._hash;
152  _table[i]._key = hashTable_[i]._key;
153  _table[i]._value = hashTable_[i]._value;
154  }
155  }
156 
157  inline const T& find(const uint& key_) const {
158  return _table[getBin(key_)]._value;
159  }
160 
161  inline bool find(const uint& key_, T& value_) const {
162  uint bin = getBin(key_);
163  value_ = _table[bin]._value;
164  if (_table[bin]._hash) return true;
165  return false;
166  }
167 
168  inline bool find(const uint& key_, T*& value_) const {
169  uint bin = getBin(key_);
170  if (_table[bin]._hash) {
171  value_ = &_table[bin]._value;
172  return true;
173  }
174  value_ = 0;
175  return false;
176  }
177 
180  inline const T& operator[](const uint& key_) const {
181  return find(key_);
182  }
183 
185  inline void add(const uint& key_, const T& value_) {
186  uint hash = HashUIntToUInt(key_);
187  uint bin = getBin(hash,key_,_table);
188  if (_table[bin]._hash) _table[bin]._value = value_;
189  else {
190  _table[bin]._hash = hash;
191  _table[bin]._key = key_;
192  _table[bin]._value = value_;
193  ++_load;
194  if (_load > _maxLoad) resize();
195  }
196  }
197 
200  inline T& add(const uint& key_) {
201  uint hash = HashUIntToUInt(key_);
202  uint bin = getBin(hash,key_,_table);
203  if (!_table[bin]._hash) {
204  _table[bin]._hash = hash;
205  _table[bin]._key = key_;
206  ++_load;
207  if (_load > _maxLoad) {
208  resize();
209  bin = getBin(hash,key_,_table);
210  }
211  }
212  return _table[bin]._value;
213  }
214 
216  inline bool remove(const uint& key_) {
217  uint i = getBin(key_);
218  if (!_table[i]._hash) return false;
219 
220  uint j = (i + 1) % _size;
221  uint k = 0;
222  while (_table[j]._hash) {
223  k = _table[j]._hash & _sizeMinusOne;
224 
225  if ((j > i && (k <= i || k > j)) ||
226  (j < i && (k <= i && k > j))) {
227  _table[i] = _table[j];
228  i = j;
229  }
230 
231  j = (j + 1) % _size;
232  }
233 
234  _table[i]._hash = 0;
235  //There is no harm in setting a default value
236  //regardless if _isUsingDefaultValue is false.
237  _table[i]._value = _defaultValue;
238  --_load;
239  return true;
240  }
241 
247  inline void clear(bool doRealloc_=true) {
248  _load = 0;
249 
250  if (doRealloc_) {
251  _size = _initSize;
252  _sizeMinusOne = _size - 1;
253  _maxLoad = static_cast<uint>(static_cast<float>(_size) * 0.75f);
254  delete[] _table;
255  _table = new TableNode[_size];
256  if (_isUsingDefaultValue)
257  for (uint i = 0; i < _size; ++i)
258  _table[i]._value = _defaultValue;
259  }
260  else {
261  if (_isUsingDefaultValue) {
262  for (uint i = 0; i < _size; ++i) {
263  _table[i]._hash = 0;
264  _table[i]._value = _defaultValue;
265  }
266  }
267  else for (uint i = 0; i < _size; ++i)
268  _table[i]._hash = 0;
269  }
270  }
271 
273  inline uint getLoad() const { return _load; }
274 
279  inline void getAllValues(T** values_) const {
280  uint numFound = 0;
281  for (uint i = 0; i < _size; i++) {
282  if (_table[i]._hash) {
283  values_[numFound] = &(_table[i]._value);
284  ++numFound;
285  }
286  }
287  }
288  private:
289  inline uint getBin(const uint& hash_, const uint& key_, const TableNode* table_) const {
290  uint bin = hash_ & _sizeMinusOne;
291  while (table_[bin]._hash && (table_[bin]._key != key_))
292  bin = (bin + 1) % _size;
293  return bin;
294  }
295 
296  inline uint getBin(const uint& key_) const {
297  return getBin(HashUIntToUInt(key_),key_,_table);
298  }
299 
300  inline void resize() {
301  uint _oldSize = _size;
302  _size = _size << 1;
303  assert(_size < 2147483649u);
304  _sizeMinusOne = _size - 1;
305  _maxLoad = static_cast<uint>(static_cast<float>(_size) * 0.75f);
306 
307  //now fill up a new table
308  TableNode* tempTable = new TableNode[_size];
309  if (_isUsingDefaultValue)
310  for (uint a = 0; a < _size; a++)
311  tempTable[a]._value = _defaultValue;
312  uint bin = 0;
313  for (uint i = 0; i < _oldSize; i++) {
314  if (_table[i]._hash) {
315  bin = getBin(_table[i]._hash,_table[i]._key,tempTable);
316  tempTable[bin]._hash = _table[i]._hash;
317  tempTable[bin]._key = _table[i]._key;
318  tempTable[bin]._value = _table[i]._value;
319  }
320  }
321  delete[] _table;
322  _table = tempTable;
323  }
324 
325  uint _load, _size, _initSize, _sizeMinusOne, _maxLoad;
326  bool _isUsingDefaultValue;
327  T _defaultValue;
328  TableNode* _table;
329  };
330  }
331 }
332 
333 #endif //UHASH_TABLE_H
HashTableUIntKeys(const HashTableUIntKeys< T > &hashTable_)
Definition: UHash.h:132
const uint MAX_3D_COMPONENT_KEY
Definition: UHash.h:40
const uint INITIAL_TABLE_SIZE
Definition: UHash.h:34
void getAllValues(T **values_) const
Definition: UHash.h:279
uint getLoad() const
Definition: UHash.h:273
Utils::uint getCompositeKey(const Math::Point< Utils::uint > &bin_)
Definition: CDGrid.h:41
HashTableUIntKeys(uint powerOf2InitialSize_, const T &defaultValue_)
Definition: UHash.h:110
ofstream log
Definition: UHashBenchmarkTests.cpp:26
bool find(const uint &key_, T *&value_) const
Definition: UHash.h:168
HashTableUIntKeys(uint powerOf2InitialSize_)
Definition: UHash.h:94
unsigned int uint
Definition: UTypes.h:39
~HashTableUIntKeys()
Definition: UHash.h:128
void add(const uint &key_, const T &value_)
Definition: UHash.h:185
void clear(bool doRealloc_=true)
Definition: UHash.h:247
const T & find(const uint &key_) const
Definition: UHash.h:157
HashTableUIntKeys & operator=(const HashTableUIntKeys< T > &hashTable_)
Definition: UHash.h:137
uint HashUIntToUInt(const uint &key_)
Definition: UHash.h:52
T & add(const uint &key_)
Definition: UHash.h:200
bool find(const uint &key_, T &value_) const
Definition: UHash.h:161
const T & operator[](const uint &key_) const
Definition: UHash.h:180