1 #ifndef GIM_HASH_TABLE_H_INCLUDED 2 #define GIM_HASH_TABLE_H_INCLUDED 37 #define GIM_INVALID_HASH 0xffffffff 38 #define GIM_DEFAULT_HASH_TABLE_SIZE 380 39 #define GIM_DEFAULT_HASH_TABLE_NODE_SIZE 4 40 #define GIM_HASH_TABLE_GROW_FACTOR 2 42 #define GIM_MIN_RADIX_SORT_SIZE 860 65 bool operator<(const GIM_HASH_TABLE_NODE<T>& other)
const 68 if (m_key < other.m_key)
return true;
75 if (m_key > other.
m_key)
return true;
82 if (m_key == other.
m_key)
return true;
105 return ((
int)(a.m_key - key));
116 return ((
int)(a.m_key - b.m_key));
124 template <
typename T>
139 #define GIM_NUM_PRIME 28 143 53ul, 97ul, 193ul, 389ul, 769ul,
144 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
145 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
146 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
147 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
148 1610612741ul, 3221225473ul, 4294967291ul};
153 GUINT result_ind = 0;
196 _node_type* nodesptr = m_nodes.
pointer();
197 GUINT start_index = (hashkey % m_table_size) * m_node_size;
198 GUINT end_index = start_index + m_node_size;
200 while (start_index < end_index)
202 GUINT value = m_hash_table[start_index];
205 if (nodesptr[value].
m_key == hashkey)
return start_index;
215 _node_type* nodesptr = m_nodes.
pointer();
217 GUINT start_index = (hashkey % m_table_size) * m_node_size;
218 GUINT end_index = start_index + m_node_size;
220 while (start_index < end_index)
222 GUINT value = m_hash_table[start_index];
227 avaliable_index = start_index;
230 else if (nodesptr[value].
m_key == hashkey)
236 return avaliable_index;
246 if (newtablesize == 0)
return;
247 if (m_node_size == 0)
return;
253 GUINT datasize = m_table_size * m_node_size;
260 GUINT datasize = m_table_size * m_node_size;
261 for (
GUINT i = 0; i < datasize; i++)
270 if (m_hash_table == NULL)
return;
281 _node_type* nodesptr = m_nodes.
pointer();
288 GUINT index = _find_avaliable_cell(nodekey);
292 btAssert(m_hash_table[index] == nodekey);
299 m_hash_table[index] = i;
309 _clear_table_memory();
311 _reserve_table_memory(newsize);
319 if (m_hash_table == NULL)
return;
320 _clear_table_memory();
326 GUINT cell_index = _find_avaliable_cell(hashkey);
331 _resize_table(m_table_size + 1);
332 GUINT cell_index = _find_avaliable_cell(hashkey);
341 if (index >= m_nodes.
size())
return false;
345 GUINT cell_index = _find_cell(m_nodes[index].
m_key);
348 btAssert(m_hash_table[cell_index] == index);
353 return this->_erase_unsorted(index);
362 GUINT cell_index = _find_cell(hashkey);
365 GUINT index = m_hash_table[cell_index];
368 return this->_erase_unsorted(index);
382 _insert_unsorted(hashkey, value);
386 GUINT cell_index = _assign_hash_table_cell(hashkey);
388 GUINT value_key = m_hash_table[cell_index];
392 m_hash_table[cell_index] = m_nodes.
size();
394 _insert_unsorted(hashkey, value);
409 _insert_unsorted(hashkey, value);
413 GUINT cell_index = _assign_hash_table_cell(hashkey);
415 GUINT value_key = m_hash_table[cell_index];
419 m_nodes[value_key] = _node_type(hashkey, value);
423 m_hash_table[cell_index] = m_nodes.
size();
425 _insert_unsorted(hashkey, value);
432 if (index >= (
GUINT)m_nodes.
size())
return false;
434 if (m_nodes.
size() < 2) m_sorted =
false;
441 if (index >= m_nodes.
size())
return false;
444 if (index < lastindex && m_hash_table != 0)
446 GUINT hashkey = m_nodes[lastindex].m_key;
450 GUINT cell_index = _find_cell(hashkey);
453 m_hash_table[cell_index] = index;
456 m_nodes.
erase(index);
467 m_nodes.
insert(_node_type(hashkey, value), pos);
468 this->check_for_switching_to_hashtable();
476 m_nodes.
push_back(_node_type(hashkey, value));
482 GUINT result_ind = 0;
484 _node_type* ptr = m_nodes.
pointer();
496 _insert_in_pos(hashkey, value, result_ind);
505 m_nodes.
push_back(_node_type(hashkey, value));
512 _node_type* ptr = m_nodes.
pointer();
520 m_nodes[result_ind] = _node_type(hashkey, value);
524 _insert_in_pos(hashkey, value, result_ind);
532 m_nodes.
push_back(_node_type(hashkey, value));
551 m_node_size = node_size;
552 m_min_hash_table_size = min_hash_table_size;
554 if (m_node_size != 0)
556 if (reserve_size != 0)
559 _reserve_table_memory(reserve_size);
569 else if (reserve_size != 0)
582 if (m_hash_table)
return true;
588 if (
size() < 2)
return true;
594 if (is_sorted())
return true;
595 if (m_nodes.
size() < 2)
return false;
597 _node_type* ptr = m_nodes.
pointer();
611 if (m_hash_table)
return false;
619 _resize_table(m_nodes.
size() + 1);
627 if (m_hash_table == NULL)
return true;
628 _clear_table_memory();
635 if (this->m_hash_table)
return true;
637 if (!(m_nodes.
size() < m_min_hash_table_size))
639 if (m_node_size == 0)
644 _resize_table(m_nodes.
size() + 1);
658 return m_nodes.
size();
664 return m_nodes[index].m_key;
672 return &m_nodes[index].
m_data;
677 return m_nodes[index].
m_data;
682 return m_nodes[index].
m_data;
694 GUINT cell_index = _find_cell(hashkey);
696 return m_hash_table[cell_index];
702 if (m_nodes[0].
m_key == hashkey)
return 0;
708 GUINT result_ind = 0;
710 _node_type* ptr = m_nodes.
pointer();
714 if (found)
return result_ind;
725 GUINT index = find(hashkey);
727 return &m_nodes[index].
m_data;
734 if (index > m_nodes.
size())
return false;
736 if (m_hash_table == NULL)
740 return this->_erase_sorted(index);
744 return this->_erase_unsorted(index);
749 return this->_erase_by_index_hash_table(index);
756 if (index > m_nodes.
size())
return false;
758 if (m_hash_table == NULL)
760 return this->_erase_unsorted(index);
764 return this->_erase_by_index_hash_table(index);
774 if (
size() == 0)
return false;
778 return this->_erase_hash_table(hashkey);
782 if (is_sorted() ==
false)
return false;
784 GUINT result_ind = find(hashkey);
787 return this->_erase_sorted(result_ind);
796 if (m_hash_table == NULL)
return;
797 GUINT datasize = m_table_size * m_node_size;
800 for (i = 0; i < datasize; i++)
816 return this->_insert_hash_table(hashkey, element);
818 if (this->is_sorted())
820 return this->_insert_sorted(hashkey, element);
822 return this->_insert_unsorted(hashkey, element);
834 return this->_insert_hash_table_replace(hashkey, element);
836 if (this->is_sorted())
838 return this->_insert_sorted_replace(hashkey, element);
840 this->_insert_unsorted(hashkey, element);
841 return m_nodes.
size();
851 return this->_insert_hash_table(hashkey, element);
853 return this->_insert_unsorted(hashkey, element);
857 #endif // GIM_CONTAINERS_H_INCLUDED bool erase_by_index_unsorted(GUINT index)
void erase(GUINT index)
fast erase
Macro for comparing Hash nodes.
int operator()(const T &a, GUINT key)
bool switch_to_hashtable()
GIM_HASH_TABLE_NODE(const GIM_HASH_TABLE_NODE &value)
gim_array< _node_type > m_nodes
The nodes.
GUINT insert_unsorted(GUINT hashkey, const T &element)
Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted...
GIM_HASH_TABLE_NODE< T > _node_type
void _rehash()
Invalidates the keys (Assigning GIM_INVALID_HASH to all) Reorders the hash keys.
Prototype for copying elements.
static const GUINT gim_prime_list[GIM_NUM_PRIME]
void insert(const T &obj, GUINT index)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
GUINT operator()(const T &a)
GUINT _assign_hash_table_cell(GUINT hashkey)
Finds an avaliable hash table cell, and resizes the table if there isn't space.
bool gim_binary_search(const T *_array, GUINT _start_i, GUINT _end_i, const T &_search_key, GUINT &_result_index)
Failsafe Iterative binary search,Template version.
bool switch_to_sorted_array()
GUINT _insert_sorted_replace(GUINT hashkey, const T &value)
#define GIM_DEFAULT_HASH_TABLE_NODE_SIZE
gim_hash_table(GUINT reserve_size=GIM_DEFAULT_HASH_TABLE_SIZE, GUINT node_size=GIM_DEFAULT_HASH_TABLE_NODE_SIZE, GUINT min_hash_table_size=GIM_INVALID_HASH)
void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
bool operator==(const GIM_HASH_TABLE_NODE< T > &other) const
void _resize_table(GUINT newsize)
Resize hash table indices.
void set_sorted(bool value)
void erase_sorted(GUINT index)
GUINT _insert_hash_table(GUINT hashkey, const T &value)
insert an element in hash table
GUINT get_key(GUINT index) const
Retrieves the hash key.
GUINT _find_cell(GUINT hashkey)
Returns the cell index.
GUINT insert(GUINT hashkey, const T &element)
Insert an element into the hash.
GUINT _insert_unsorted(GUINT hashkey, const T &value)
Fast insertion in m_nodes array.
bool operator>(const GIM_HASH_TABLE_NODE< T > &other) const
bool _erase_sorted(GUINT index)
Sorted array data management. The hash table has the indices to the corresponding m_nodes array...
T * get_value_by_index(GUINT index)
Retrieves the value by index.
bool erase_by_index(GUINT index)
GUINT gim_next_prime(GUINT number)
GIM_HASH_TABLE_NODE(GUINT key, const T &data)
GUINT _find_avaliable_cell(GUINT hashkey)
Find the avaliable cell for the hashkey, and return an existing cell if it has the same hash key...
Very simple array container with fast access and simd memory.
GUINT size() const
Retrieves the amount of keys.
GUINT find(GUINT hashkey)
Finds the index of the element with the key.
bool erase_by_key(GUINT hashkey)
GUINT m_min_hash_table_size
bool gim_binary_search_ex(const T *_array, GUINT _start_i, GUINT _end_i, GUINT &_result_index, const KEYCLASS &_search_key, COMP_CLASS _comp_macro)
Failsafe Iterative binary search,.
void _clear_table_memory()
Clear all memory for the hash table.
GUINT _insert_hash_table_replace(GUINT hashkey, const T &value)
insert an element in hash table.
GUINT insert_override(GUINT hashkey, const T &element)
Insert an element into the hash, and could overrite an existing object with the same hash...
void _insert_in_pos(GUINT hashkey, const T &value, GUINT pos)
Insert in position ordered.
const T & operator[](GUINT index) const
Macro for getting the key.
void gim_radix_sort(T *array, GUINT element_count, GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
Sorts array in place. For generic use.
GUINT _insert_sorted(GUINT hashkey, const T &value)
Insert an element in an ordered array.
void _reserve_table_memory(GUINT newtablesize)
reserves the memory for the hash table.
void * gim_alloc(size_t size)
Standar Memory functions.
void _destroy()
Destroy hash table memory.
A compact hash table implementation.
GUINT * m_hash_table
Hash table data management. The hash table has the indices to the corresponding m_nodes array...
static DBVT_INLINE btDbvtNode * sort(btDbvtNode *n, btDbvtNode *&r)
bool _erase_by_index_hash_table(GUINT index)
erase by index in hash table
#define GIM_DEFAULT_HASH_TABLE_SIZE
void gim_sort_hash_node_array(T *array, GUINT array_count)
Sorting for hash table.
bool reserve(GUINT size)
public operations
#define GIM_MIN_RADIX_SORT_SIZE
calibrated on a PIII
void push_back(const T &obj)
T & operator[](GUINT index)
bool _erase_unsorted(GUINT index)
faster, but unsorted
#define GIM_INVALID_HASH
A very very high value.
Macro for comparing the key and the element.
T * get_value(GUINT hashkey)
Retrieves the value associated with the index.
bool _erase_hash_table(GUINT hashkey)
erase by key in hash table
int operator()(const T &a, const T &b)
bool check_for_switching_to_hashtable()
If the container reaches the.