41template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE = 128,
int STACK_SIZE = 1>
class HashTable
73 IndexT Add(
const KEYTYPE& key,
const VALUETYPE& value);
112 friend class HashTable<KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE>;
130 template <
typename HASHKEY>
const uint32_t
GetHashCode(
const typename std::enable_if<std::is_integral<HASHKEY>::value, HASHKEY>::type& key)
const {
return uint32_t(key % this->hashArray.
Size()); };
132 template <
typename HASHKEY>
const uint32_t
GetHashCode(
const HASHKEY& key)
const {
return key.HashCode() % this->hashArray.
Size(); };
134 template <
typename HASHKEY>
const uint32_t
GetHashCode(
const typename std::enable_if<std::is_pointer<HASHKEY>::value, HASHKEY>::type& key)
const {
return key->HashCode() % this->hashArray.
Size(); }
140template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
145 for (
int i = 0; i < this->hashArray.Size(); i++)
147 for (
int j = 0; j < this->hashArray[i].Size();j++)
149 keys.
Append(this->hashArray[i][j].Key());
158template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
163 for (
int i = 0; i < this->hashArray.Size(); i++)
165 for (
int j = 0; j < this->hashArray[i].Size(); j++)
167 vals.
Append(this->hashArray[i][j].Value());
176template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
185 ret.
arr = &this->hashArray;
187 for (i = 0; i < this->hashArray.Size(); i++)
189 if (this->hashArray[i].Size() != 0)
193 ret.
val = &this->hashArray[i].Front().Value();
194 ret.
key = &this->hashArray[i].Front().Key();
204template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
213 ret.
arr = &this->hashArray;
220template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
222 hashArray(TABLE_SIZE),
223 bulkDirty(TABLE_SIZE),
233template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
235 hashArray(rhs.hashArray),
236 bulkDirty(rhs.bulkDirty),
237 inBulkAdd(rhs.inBulkAdd),
246template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
248 hashArray(
std::move(rhs.hashArray)),
249 bulkDirty(rhs.bulkDirty),
250 inBulkAdd(rhs.inBulkAdd),
259template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
267 this->size = rhs.
size;
274template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
280 this->hashArray = std::move(rhs.hashArray);
281 this->bulkDirty = rhs.bulkDirty;
282 this->size = rhs.size;
290template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
296 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
298 int numHashElements = hashElements.
Size();
299 #if NEBULA_BOUNDSCHECKS
302 if (1 == numHashElements)
305 return hashElements[0].Value();
311 IndexT hashElementIndex = hashElements.template BinarySearchIndex<KEYTYPE>(key);
312 #if NEBULA_BOUNDSCHECKS
315 return hashElements[hashElementIndex].Value();
322template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
332template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
336 return this->hashArray.Size();
342template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
347 SizeT num = this->hashArray.Size();
348 for (i = 0; i < num; i++)
350 this->hashArray[i].Clear();
358template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
363 SizeT num = this->hashArray.Size();
364 for (i = 0; i < num; i++)
366 this->hashArray[i].Reset();
374template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
378 return (0 == this->size);
384template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
389 this->inBulkAdd =
true;
390 this->bulkDirty.Fill(
false);
396template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
400 return this->inBulkAdd;
406template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
410#if NEBULA_BOUNDSCHECKS
413 uint32_t hashIndex = GetHashCode<KEYTYPE>(kvp.
Key());
417 ret = this->hashArray[hashIndex].Size();
418 this->hashArray[hashIndex].Append(kvp);
419 this->bulkDirty[hashIndex] =
true;
422 ret = this->hashArray[hashIndex].InsertSorted(kvp);
431template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
436 return this->Add(kvp);
442template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
447 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
450 if (hashElements.
Size() == 0)
452 elementIndex = this->Add(key, VALUETYPE());
458 elementIndex = hashElements.template FindIndex<KEYTYPE>(key);
460 elementIndex = hashElements.template BinarySearchIndex<KEYTYPE>(key);
464 elementIndex = this->Add(key, VALUETYPE());
467 return hashElements[elementIndex].Value();
473template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
479 for (i = 0; i < this->bulkDirty.Size(); i++)
481 if (this->bulkDirty[i])
483 this->hashArray[i].Sort();
484 this->bulkDirty[i] =
false;
487 this->inBulkAdd =
false;
493template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
499 for (i = 0; i < rhs.
hashArray.Size(); i++)
502 for (j = 0; j < rhs.
hashArray[i].Size(); j++)
510template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
514 #if NEBULA_BOUNDSCHECKS
518 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
520 IndexT hashElementIndex = hashElements.template BinarySearchIndex<KEYTYPE>(key);
521 #if NEBULA_BOUNDSCHECKS
531template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
535#if NEBULA_BOUNDSCHECKS
538 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
540#if NEBULA_BOUNDSCHECKS
550template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
556 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
558 if (hashElements.
Size() == 0)
return false;
563 hashElementIndex = hashElements.template FindIndex<KEYTYPE>(key);
565 hashElementIndex = hashElements.template BinarySearchIndex<KEYTYPE>(key);
578template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
582 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
586 hashElementIndex = hashElements.template FindIndex<KEYTYPE>(key);
588 hashElementIndex = hashElements.template BinarySearchIndex<KEYTYPE>(key);
589 return hashElementIndex;
595template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
599 uint32_t hashIndex = GetHashCode<KEYTYPE>(key);
601 return hashElements[i].Value();
607template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
613 int num = this->hashArray.
Size();
614 for (i = 0; i < num; i++)
616 if (this->hashArray[i].Size() > 0)
627template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
671template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
675 return this->key == rhs.
key;
681template<
class KEYTYPE,
class VALUETYPE,
int TABLE_SIZE,
int STACK_SIZE>
685 return this->key != rhs.
key;
Nebula's dynamic array class.
Definition array.h:60
void Append(const TYPE &first, const ELEM_TYPE &... elements)
Append multiple elements to the end of the array.
Definition array.h:1334
void AppendArray(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs)
append the contents of an array to this array
Definition array.h:768
void EraseIndex(IndexT index)
erase element at index, keep sorting intact
Definition array.h:1036
const SizeT Size() const
get number of elements in array
Definition array.h:880
Implements a fixed size one-dimensional array.
Definition fixedarray.h:20
const SizeT Size() const
get number of elements
Definition fixedarray.h:532
Definition hashtable.h:98
IndexT bucketIndex
Definition hashtable.h:115
Iterator & operator++(int)
progress to next item in the hash table
Definition hashtable.h:629
const bool operator!=(const Iterator &rhs) const
check if iterator is identical
Definition hashtable.h:683
const bool operator==(const Iterator &rhs) const
check if iterator is identical
Definition hashtable.h:673
KEYTYPE const * key
Definition hashtable.h:110
uint32_t hashIndex
Definition hashtable.h:114
FixedArray< StackArray< KeyValuePair< KEYTYPE, VALUETYPE >, STACK_SIZE > > * arr
Definition hashtable.h:113
VALUETYPE * val
the current value
Definition hashtable.h:109
Organizes key/value pairs by a hash code.
Definition hashtable.h:42
StackArray< KeyValuePair< KEYTYPE, VALUETYPE >, STACK_SIZE > Content() const
return array of all key/value pairs in the table (slow)
Definition hashtable.h:609
void EndBulkAdd()
end bulk adding, which sorts all affected tables
Definition hashtable.h:475
IndexT FindIndex(const KEYTYPE &key) const
find index in bucket
Definition hashtable.h:580
HashTable(HashTable< KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE > &&rhs)
move constructor
Definition hashtable.h:247
VALUETYPE & Emplace(const KEYTYPE &key)
adds element only if it doesn't exist, and return reference to it
Definition hashtable.h:444
void Reset()
reset the hashtable arrays to 0 size, but don't run destructor
Definition hashtable.h:360
void operator=(const HashTable< KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE > &rhs)
assignment operator
Definition hashtable.h:261
FixedArray< bool > bulkDirty
Definition hashtable.h:126
const uint32_t GetHashCode(const typename std::enable_if< std::is_integral< HASHKEY >::value, HASHKEY >::type &key) const
if type is integral, just use that value directly
Definition hashtable.h:130
VALUETYPE & ValueAtIndex(const KEYTYPE &key, IndexT i) const
get value from key and bucket
Definition hashtable.h:597
VALUETYPE & operator[](const KEYTYPE &key) const
read/write [] operator, assertion if key not found
Definition hashtable.h:292
StackArray< KEYTYPE, STACK_SIZE > KeysAsArray() const
get all keys as an Util::Array (slow)
Definition hashtable.h:142
int size
Definition hashtable.h:124
IndexT Add(const KeyValuePair< KEYTYPE, VALUETYPE > &kvp)
add a key/value pair object to the hash table, returns index within hash array where item is stored
Definition hashtable.h:408
HashTable()
default constructor
Definition hashtable.h:221
SizeT Size() const
return current number of values in the hashtable
Definition hashtable.h:324
const uint32_t GetHashCode(const HASHKEY &key) const
if not, call the function on HashCode on HASHKEY
Definition hashtable.h:132
bool IsEmpty() const
return true if empty
Definition hashtable.h:376
HashTable(const HashTable< KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE > &rhs)
copy constructor
Definition hashtable.h:234
void Clear()
clear the hashtable
Definition hashtable.h:344
void Erase(const KEYTYPE &key)
erase an entry
Definition hashtable.h:512
SizeT Capacity() const
return fixed-size capacity of the hash table
Definition hashtable.h:334
void BeginBulkAdd()
begin bulk adding to the hashtable, which will amortize the cost of sorting the hash buckets upon end
Definition hashtable.h:386
void Merge(const HashTable< KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE > &rhs)
merge two dictionaries
Definition hashtable.h:495
bool Contains(const KEYTYPE &key) const
return true if key exists in the array
Definition hashtable.h:552
StackArray< VALUETYPE, STACK_SIZE > ValuesAsArray() const
get all keys as an Util::Array (slow)
Definition hashtable.h:160
bool inBulkAdd
Definition hashtable.h:127
void EraseIndex(const KEYTYPE &key, IndexT i)
erase an entry with known index
Definition hashtable.h:533
Iterator Begin()
get iterator to first element
Definition hashtable.h:178
const bool IsBulkAdd() const
returns true if currently bulk adding
Definition hashtable.h:398
const uint32_t GetHashCode(const typename std::enable_if< std::is_pointer< HASHKEY >::value, HASHKEY >::type &key) const
if type is pointer, convert using questionable method
Definition hashtable.h:134
Iterator End()
get iterator to last element
Definition hashtable.h:206
FixedArray< StackArray< KeyValuePair< KEYTYPE, VALUETYPE >, STACK_SIZE > > hashArray
Definition hashtable.h:123
void operator=(HashTable< KEYTYPE, VALUETYPE, TABLE_SIZE, STACK_SIZE > &&rhs)
move assignment operator
Definition hashtable.h:276
IndexT Add(const KEYTYPE &key, const VALUETYPE &value)
add a key and associated value
Definition hashtable.h:433
Key/Value pair objects are used by most assiociative container classes, like Dictionary or HashTable.
Definition keyvaluepair.h:19
const KEYTYPE & Key() const
read access to key
Definition keyvaluepair.h:282
#define n_assert(exp)
Definition debug.h:50
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
Array< TYPE, STACK_SIZE > StackArray
Definition array.h:1881
Nebula's scalar datatype.
static const int InvalidIndex
Definition types.h:54
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48