32 #include "hashfuncs.h" 33 #include "error_macros.h" 35 #include "os/memory.h" 42 static _FORCE_INLINE_ uint32_t hash(
const String &p_string) {
return p_string.hash(); }
43 static _FORCE_INLINE_ uint32_t hash(
const char *p_cstr) {
return hash_djb2(p_cstr); }
44 static _FORCE_INLINE_ uint32_t hash(
const uint64_t p_int) {
54 static _FORCE_INLINE_ uint32_t hash(
const int64_t p_int) {
return hash(uint64_t(p_int)); }
57 static _FORCE_INLINE_ uint32_t hash(
const uint32_t p_int) {
return p_int; }
58 static _FORCE_INLINE_ uint32_t hash(
const int32_t p_int) {
return (uint32_t)p_int; }
59 static _FORCE_INLINE_ uint32_t hash(
const uint16_t p_int) {
return p_int; }
60 static _FORCE_INLINE_ uint32_t hash(
const int16_t p_int) {
return (uint32_t)p_int; }
61 static _FORCE_INLINE_ uint32_t hash(
const uint8_t p_int) {
return p_int; }
62 static _FORCE_INLINE_ uint32_t hash(
const int8_t p_int) {
return (uint32_t)p_int; }
63 static _FORCE_INLINE_ uint32_t hash(
const wchar_t p_wchar) {
return (uint32_t)p_wchar; }
83 template<
class TKey,
class TData,
class Hasher=HashMapHahserDefault,u
int8_t MIN_HASH_TABLE_POWER=3,u
int8_t RELATIONSHIP=8>
93 Pair(
const TKey& p_key,
const TData& p_data) { key=p_key; data=p_data; }
108 uint8_t hash_table_power;
111 void make_hash_table() {
113 ERR_FAIL_COND( hash_table );
116 hash_table = memnew_arr( Entry*, (1<<MIN_HASH_TABLE_POWER) );
118 hash_table_power = MIN_HASH_TABLE_POWER;
120 for (
int i=0;i<(1<<MIN_HASH_TABLE_POWER);i++)
124 void erase_hash_table() {
126 ERR_FAIL_COND(elements);
128 memdelete_arr( hash_table );
134 void check_hash_table() {
136 int new_hash_table_power=-1;
138 if ((
int)elements > ( (1<<hash_table_power) * RELATIONSHIP ) ) {
140 new_hash_table_power=hash_table_power+1;
142 while( (
int)elements > ( (1<<new_hash_table_power) * RELATIONSHIP ) ) {
144 new_hash_table_power++;
147 }
else if ( (hash_table_power>(
int)MIN_HASH_TABLE_POWER) && ((
int)elements < ( (1<<(hash_table_power-1)) * RELATIONSHIP ) ) ) {
150 new_hash_table_power=hash_table_power-1;
152 while( (
int)elements < ( (1<<(new_hash_table_power-1)) * RELATIONSHIP ) ) {
154 new_hash_table_power--;
157 if (new_hash_table_power<(
int)MIN_HASH_TABLE_POWER)
158 new_hash_table_power=MIN_HASH_TABLE_POWER;
162 if (new_hash_table_power==-1)
165 Entry ** new_hash_table = memnew_arr( Entry*, (1<<new_hash_table_power) );
166 if (!new_hash_table) {
168 ERR_PRINT(
"Out of Memory");
172 for (
int i=0;i<(1<<new_hash_table_power);i++) {
177 for (
int i=0;i<(1<<hash_table_power);i++) {
179 while( hash_table[i] ) {
181 Entry *se=hash_table[i];
182 hash_table[i]=se->next;
183 int new_pos = se->hash & ((1<<new_hash_table_power)-1);
184 se->next=new_hash_table[new_pos];
185 new_hash_table[new_pos]=se;
191 memdelete_arr( hash_table );
192 hash_table=new_hash_table;
193 hash_table_power=new_hash_table_power;
199 _FORCE_INLINE_
const Entry * get_entry(
const TKey& p_key )
const {
201 uint32_t hash = Hasher::hash( p_key );
202 uint32_t index = hash&((1<<hash_table_power)-1);
204 Entry *e = hash_table[index];
209 if (e->hash == hash && e->pair.key == p_key ) {
221 Entry * create_entry(
const TKey& p_key) {
224 Entry *e = memnew( Entry );
225 ERR_FAIL_COND_V(!e,NULL);
226 uint32_t hash = Hasher::hash( p_key );
227 uint32_t index = hash&((1<<hash_table_power)-1);
228 e->next = hash_table[index];
239 void copy_from(
const HashMap& p_t) {
246 if (!p_t.hash_table || p_t.hash_table_power==0)
249 hash_table = memnew_arr(Entry*,1<<p_t.hash_table_power);
250 hash_table_power=p_t.hash_table_power;
251 elements=p_t.elements;
253 for (
int i=0;i<( 1<<p_t.hash_table_power );i++) {
258 const Entry *e = p_t.hash_table[i];
262 Entry *le = memnew( Entry );
267 le->next=hash_table[i];
281 void set(
const TKey& p_key,
const TData& p_data ) {
283 set(
Pair( p_key, p_data ) );
287 void set(
const Pair& p_pair ) {
293 e =
const_cast<Entry*
>( get_entry(p_pair.key) );
299 e=create_entry(p_pair.key);
305 e->pair.data = p_pair.data;
310 bool has(
const TKey& p_key )
const {
312 return getptr(p_key)!=NULL;
321 const TData&
get(
const TKey& p_key )
const {
323 const TData* res = getptr(p_key);
324 ERR_FAIL_COND_V(!res,*res);
328 TData&
get(
const TKey& p_key ) {
330 TData* res = getptr(p_key);
331 ERR_FAIL_COND_V(!res,*res);
341 _FORCE_INLINE_ TData*
getptr(
const TKey& p_key ) {
346 Entry *e=
const_cast<Entry*
>(get_entry(p_key ));
349 return &e->pair.data;
355 _FORCE_INLINE_
const TData* getptr(
const TKey& p_key )
const {
360 const Entry *e=
const_cast<Entry*
>(get_entry(p_key ));
363 return &e->pair.data;
375 _FORCE_INLINE_ TData*
custom_getptr( C p_custom_key,uint32_t p_custom_hash ) {
380 uint32_t hash = p_custom_hash;
381 uint32_t index = hash&((1<<hash_table_power)-1);
383 Entry *e = hash_table[index];
388 if (e->hash == hash && e->pair.key == p_custom_key ) {
391 return &e->pair.data;
401 _FORCE_INLINE_
const TData* custom_getptr( C p_custom_key,uint32_t p_custom_hash )
const {
406 uint32_t hash = p_custom_hash;
407 uint32_t index = hash&((1<<hash_table_power)-1);
409 const Entry *e = hash_table[index];
414 if (e->hash == hash && e->pair.key == p_custom_key ) {
417 return &e->pair.data;
436 uint32_t hash = Hasher::hash( p_key );
437 uint32_t index = hash&((1<<hash_table_power)-1);
440 Entry *e = hash_table[index];
445 if (e->hash == hash && e->pair.key == p_key ) {
452 hash_table[index]=e->next;
474 inline const TData& operator[](
const TKey& p_key)
const {
478 inline TData& operator[](
const TKey& p_key ) {
484 e =
const_cast<Entry*
>( get_entry(p_key) );
489 e=create_entry(p_key);
491 return *(TData*)NULL;
514 const TKey*
next(
const TKey* p_key)
const {
516 if (!hash_table)
return NULL;
520 for (
int i=0;i<(1<<hash_table_power);i++) {
523 return &hash_table[i]->pair.key;
529 const Entry *e = get_entry( *p_key );
530 ERR_FAIL_COND_V( !e, NULL );
534 return &e->next->pair.key;
537 uint32_t index = e->hash&((1<<hash_table_power)-1);
539 for (
int i=index;i<(1<<hash_table_power);i++) {
542 return &hash_table[i]->pair.key;
555 inline unsigned int size()
const {
560 inline bool empty()
const {
569 for (
int i=0;i<(1<<hash_table_power);i++) {
571 while (hash_table[i]) {
573 Entry *e=hash_table[i];
574 hash_table[i]=e->next;
579 memdelete_arr( hash_table );
588 void operator=(
const HashMap& p_table) {
602 for(
int i=0;i<(1<<hash_table_power);i++) {
604 Entry *e=hash_table[i];
Element * push_back(const T &value)
Definition: list.h:220
Definition: hash_map.h:84
Definition: hash_map.h:87
Definition: hash_map.h:39
const TKey * next(const TKey *p_key) const
Definition: hash_map.h:514
bool erase(const TKey &p_key)
Definition: hash_map.h:431
_FORCE_INLINE_ TData * getptr(const TKey &p_key)
Definition: hash_map.h:341
_FORCE_INLINE_ TData * custom_getptr(C p_custom_key, uint32_t p_custom_hash)
Definition: hash_map.h:375