15 #include "../config/config.hpp"
31 { other.reusable.
Copy(reusable); }
38 int id = reusable.
Last();
63 template<
typename Derived>
77 template<
typename Derived>
116 template<
typename ItemT>
125 ItemT*
Get(
int p1,
int p2);
126 ItemT*
Get(
int p1,
int p2,
int p3,
int p4);
129 ItemT*
Peek(
int p1,
int p2)
const;
130 ItemT*
Peek(
int p1,
int p2,
int p3,
int p4)
const;
133 template<
typename OtherT>
134 ItemT*
Get(OtherT* i1, OtherT* i2)
135 {
return Get(i1->id, i2->id); }
137 template<
typename OtherT>
138 ItemT*
Get(OtherT* i1, OtherT* i2, OtherT* i3, OtherT* i4)
139 {
return Get(i1->id, i2->id, i3->id, i4->id); }
141 template<
typename OtherT>
142 ItemT*
Peek(OtherT* i1, OtherT* i2)
const
143 {
return Peek(i1->id, i2->id); }
145 template<
typename OtherT>
146 ItemT*
Peek(OtherT* i1, OtherT* i2, OtherT* i3, OtherT* i4)
const
147 {
return Peek(i1->id, i2->id, i3->id, i4->id); }
156 void Reparent(ItemT* item,
int new_p1,
int new_p2);
157 void Reparent(ItemT* item,
int new_p1,
int new_p2,
int new_p3,
int new_p4);
192 inline int hash(
int p1,
int p2)
const
193 {
return (984120265*p1 + 125965121*p2) &
mask; }
195 inline int hash(
int p1,
int p2,
int p3)
const
196 {
return (984120265*p1 + 125965121*p2 + 495698413*p3) &
mask; }
200 {
return hash(item->
p1, item->
p2); }
203 {
return hash(item->
p1, item->
p2, item->
p3); }
205 ItemT*
SearchList(ItemT* item,
int p1,
int p2)
const;
206 ItemT*
SearchList(ItemT* item,
int p1,
int p2,
int p3)
const;
208 void Insert(
int idx, ItemT* item);
221 template<
typename ItemT>
225 if (init_size & mask)
227 MFEM_ABORT(
"HashTable(): init_size size must be a power of two.");
230 table =
new ItemT*[init_size];
231 std::memset(table, 0, init_size *
sizeof(ItemT*));
236 template<
typename ItemT>
238 : mask(other.mask), num_items(0), id_gen(other.id_gen)
241 table =
new ItemT*[size];
242 std::memset(
table, 0, size *
sizeof(ItemT*));
249 ItemT* item =
new ItemT(*it);
255 template<
typename ItemT>
269 inline void sort3(
int &a,
int &b,
int &c)
271 if (a > b) { std::swap(a, b); }
272 if (a > c) { std::swap(a, c); }
273 if (b > c) { std::swap(b, c); }
276 inline void sort4(
int &a,
int &b,
int &c,
int &d)
278 if (a > b) { std::swap(a, b); }
279 if (a > c) { std::swap(a, c); }
280 if (a > d) { std::swap(a, d); }
286 template<
typename ItemT>
289 if (p1 > p2) { std::swap(p1, p2); }
290 return SearchList(table[hash(p1, p2)], p1, p2);
293 template<
typename ItemT>
296 internal::sort4(p1, p2, p3, p4);
297 return SearchList(table[hash(p1, p2, p3)], p1, p2, p3);
300 template<
typename ItemT>
304 item->next = table[idx];
309 template<
typename ItemT>
313 if (p1 > p2) { std::swap(p1, p2); }
314 int idx = hash(p1, p2);
315 ItemT* node = SearchList(table[idx], p1, p2);
316 if (node) {
return node; }
319 ItemT* newitem =
new ItemT(id_gen.Get());
324 Insert(idx, newitem);
327 if (id_to_item.Size() <= newitem->id)
329 id_to_item.SetSize(newitem->id + 1, NULL);
331 id_to_item[newitem->id] = newitem;
337 template<
typename ItemT>
341 internal::sort4(p1, p2, p3, p4);
342 int idx = hash(p1, p2, p3);
343 ItemT* node = SearchList(table[idx], p1, p2, p3);
344 if (node) {
return node; }
347 ItemT* newitem =
new ItemT(id_gen.Get());
353 Insert(idx, newitem);
356 if (id_to_item.Size() <= newitem->id)
358 id_to_item.SetSize(newitem->id + 1, NULL);
360 id_to_item[newitem->id] = newitem;
366 template<
typename ItemT>
371 if (item->p1 == p1 && item->p2 == p2) {
return item; }
377 template<
typename ItemT>
382 if (item->p1 == p1 && item->p2 == p2 && item->p3 == p3) {
return item; }
388 template<
typename ItemT>
391 const int fill_factor = 2;
392 int old_size = mask+1;
395 if (num_items > old_size * fill_factor)
400 int new_size = 2*old_size;
401 table =
new ItemT*[new_size];
402 memset(table, 0, new_size *
sizeof(ItemT*));
406 std::cout << _MFEM_FUNC_NAME <<
": rehashing to size " << new_size
414 Insert(hash(it), it);
419 template<
typename ItemT>
423 ItemT** ptr = table + hash(item);
432 ptr = &((*ptr)->next);
434 MFEM_ABORT(
"HashTable<>::Unlink: item not found!");
437 template<
typename ItemT>
444 id_to_item[item->id] = NULL;
447 id_gen.Reuse(item->id);
452 template<
typename ItemT>
457 if (new_p1 > new_p2) { std::swap(new_p1, new_p2); }
462 int new_idx = hash(new_p1, new_p2);
463 Insert(new_idx, item);
466 template<
typename ItemT>
468 int new_p1,
int new_p2,
int new_p3,
int new_p4)
472 internal::sort4(new_p1, new_p2, new_p3, new_p4);
478 int new_idx = hash(new_p1, new_p2, new_p3);
479 Insert(new_idx, item);
482 template<
typename ItemT>
496 template<
typename ItemT>
503 template<
typename ItemT>
int Size() const
Logical size of the array.
Iterator(const HashTable< ItemT > &table)
HashTable(int init_size=32 *1024)
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
void Copy(Array ©) const
Create a copy of the current array.
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.
IdGenerator(const IdGenerator &other)
const HashTable< ItemT > & hash_table
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 SetSize(int nsize)
Change logical size of the array, keep existing entries.
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
void PrintMemoryDetail() 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