15 #include "../config/config.hpp"
35 int id = reusable.
Last();
60 template<
typename Derived>
73 template<
typename Derived>
111 template<
typename ItemT>
119 ItemT*
Get(
int p1,
int p2);
120 ItemT*
Get(
int p1,
int p2,
int p3,
int p4);
123 ItemT*
Peek(
int p1,
int p2)
const;
124 ItemT*
Peek(
int p1,
int p2,
int p3,
int p4)
const;
127 template<
typename OtherT>
128 ItemT*
Get(OtherT* i1, OtherT* i2)
129 {
return Get(i1->id, i2->id); }
131 template<
typename OtherT>
132 ItemT*
Get(OtherT* i1, OtherT* i2, OtherT* i3, OtherT* i4)
133 {
return Get(i1->id, i2->id, i3->id, i4->id); }
135 template<
typename OtherT>
136 ItemT*
Peek(OtherT* i1, OtherT* i2)
const
137 {
return Peek(i1->id, i2->id); }
139 template<
typename OtherT>
140 ItemT*
Peek(OtherT* i1, OtherT* i2, OtherT* i3, OtherT* i4)
const
141 {
return Peek(i1->id, i2->id, i3->id, i4->id); }
150 void Reparent(ItemT* item,
int new_p1,
int new_p2);
151 void Reparent(ItemT* item,
int new_p1,
int new_p2,
int new_p3,
int new_p4);
184 inline int hash(
int p1,
int p2)
const
185 {
return (984120265*p1 + 125965121*p2) &
mask; }
187 inline int hash(
int p1,
int p2,
int p3)
const
188 {
return (984120265*p1 + 125965121*p2 + 495698413*p3) &
mask; }
192 {
return hash(item->
p1, item->
p2); }
195 {
return hash(item->
p1, item->
p2, item->
p3); }
197 ItemT*
SearchList(ItemT* item,
int p1,
int p2)
const;
198 ItemT*
SearchList(ItemT* item,
int p1,
int p2,
int p3)
const;
200 void Insert(
int idx, ItemT* item);
213 template<
typename ItemT>
217 if (init_size & mask)
218 mfem_error(
"HashTable(): init_size size must be a power of two.");
220 table =
new ItemT*[init_size];
221 memset(table, 0, init_size *
sizeof(ItemT*));
226 template<
typename ItemT>
238 inline void sort3(
int &a,
int &b,
int &c)
245 inline void sort4(
int &a,
int &b,
int &c,
int &d)
255 template<
typename ItemT>
259 return SearchList(table[hash(p1, p2)], p1, p2);
262 template<
typename ItemT>
265 internal::sort4(p1, p2, p3, p4);
266 return SearchList(table[hash(p1, p2, p3)], p1, p2, p3);
269 template<
typename ItemT>
273 item->next = table[idx];
278 template<
typename ItemT>
283 int idx = hash(p1, p2);
284 ItemT* node = SearchList(table[idx], p1, p2);
285 if (node)
return node;
288 ItemT* newitem =
new ItemT(id_gen.Get());
293 Insert(idx, newitem);
296 if (id_to_item.Size() <= newitem->id) {
297 id_to_item.SetSize(newitem->id + 1, NULL);
299 id_to_item[newitem->id] = newitem;
305 template<
typename ItemT>
309 internal::sort4(p1, p2, p3, p4);
310 int idx = hash(p1, p2, p3);
311 ItemT* node = SearchList(table[idx], p1, p2, p3);
312 if (node)
return node;
315 ItemT* newitem =
new ItemT(id_gen.Get());
321 Insert(idx, newitem);
324 if (id_to_item.Size() <= newitem->id) {
325 id_to_item.SetSize(newitem->id + 1, NULL);
327 id_to_item[newitem->id] = newitem;
333 template<
typename ItemT>
338 if (item->p1 == p1 && item->p2 == p2)
return item;
344 template<
typename ItemT>
349 if (item->p1 == p1 && item->p2 == p2 && item->p3 == p3)
return item;
355 template<
typename ItemT>
358 const int fill_factor = 2;
359 int old_size = mask+1;
362 if (num_items > old_size * fill_factor)
367 int new_size = 2*old_size;
368 table =
new ItemT*[new_size];
369 memset(table, 0, new_size *
sizeof(ItemT*));
373 std::cout << _MFEM_FUNC_NAME <<
": rehashing to size " << new_size
380 Insert(hash(it), it);
384 template<
typename ItemT>
388 ItemT** ptr = table + hash(item);
397 ptr = &((*ptr)->next);
399 mfem_error(
"HashTable<>::Unlink: item not found!");
402 template<
typename ItemT>
409 id_to_item[item->id] = NULL;
412 id_gen.Reuse(item->id);
417 template<
typename ItemT>
422 if (new_p1 > new_p2)
std::swap(new_p1, new_p2);
427 int new_idx = hash(new_p1, new_p2);
428 Insert(new_idx, item);
431 template<
typename ItemT>
433 int new_p1,
int new_p2,
int new_p3,
int new_p4)
437 internal::sort4(new_p1, new_p2, new_p3, new_p4);
443 int new_idx = hash(new_p1, new_p2, new_p3);
444 Insert(new_idx, item);
447 template<
typename ItemT>
461 template<
typename ItemT>
464 return sizeof(*this) +
int Size() const
Logical size of the array.
HashTable< ItemT > & hash_table
HashTable(int init_size=32 *1024)
Iterator(HashTable< ItemT > &table)
Iterator over items contained in the HashTable.
long MemoryUsage() const
Return total size of allocated memory (tables plus items), in bytes.
void Reparent(ItemT *item, int new_p1, int new_p2)
Make an item hashed under different parent IDs.
int hash(const Hashed2< ItemT > *item) const
ItemT & operator*() const
void Rehash()
Check table load and resize if necessary.
int hash(int p1, int p2) const
void Delete(ItemT *item)
Remove an item from the hash table and also delete the item itself.
ItemT * Get(OtherT *i1, OtherT *i2)
ItemT * Get(int p1, int p2)
Get an item whose parents are p1, p2... Create it if it doesn't exist.
ItemT * Peek(int id) const
Obtains an item given its ID.
int Append(const T &el)
Append element to array, resize if necessary.
ItemT * SearchList(ItemT *item, int p1, int p2) const
ItemT * Peek(OtherT *i1, OtherT *i2, OtherT *i3, OtherT *i4) const
int hash(const Hashed4< ItemT > *item) const
Array< ItemT * > id_to_item
mapping table for the Peek(id) method
ItemT * Peek(int p1, int p2) const
Get an item whose parents are p1, p2... Return NULL if it doesn't exist.
void swap(Vector *v1, Vector *v2)
void mfem_error(const char *msg)
void DeleteLast()
Delete the last entry.
void Reuse(int id)
Return an ID previously generated by 'Get'.
void Insert(int idx, ItemT *item)
IdGenerator(int first_id=0)
T & Last()
Return the last element in the array.
ItemT * Peek(OtherT *i1, OtherT *i2) const
ItemT * operator->() const
ItemT * Get(OtherT *i1, OtherT *i2, OtherT *i3, OtherT *i4)
int Get()
Generate a unique ID.
IdGenerator id_gen
id generator for new items
int hash(int p1, int p2, int p3) const