35 # include <tpl_dynArray.H> 37 # include <hash-fct.H> 38 # include <tpl_dynArray.H> 39 # include <hash-dry.H> 53 using namespace Aleph;
76 template <
typename Key,
class BucketType,
class Cmp>
77 class GenLhashTable :
public HashStats<GenLhashTable<Key, BucketType, Cmp>>
79 friend class HashStats<GenLhashTable<Key, BucketType, Cmp>>;
83 using Bucket = BucketType;
85 using Hash_Fct = std::function<size_t(const Key &)>;
87 using Hash_Fct_Ptr = size_t (*) (
const Key &);
91 using Item_Type = Key;
115 size_t busy_slots_counter;
116 bool remove_all_buckets;
121 Cmp & get_compare() {
return cmp; }
123 const Cmp & get_compare()
const {
return cmp; }
127 GenLhashTable(
size_t table_size, Hash_Fct __hash_fct, Cmp __cmp,
128 float __lower_alpha,
float __upper_alpha,
129 bool __remove_all_buckets,
bool __with_resize)
130 : hash_fct(__hash_fct), table(
nullptr),
131 len(Primes::next_prime(table_size)), cmp(__cmp),
132 lower_alpha(__lower_alpha), upper_alpha(__upper_alpha),
133 N(0), busy_slots_counter(0), remove_all_buckets(__remove_all_buckets),
134 with_resize(__with_resize)
150 Hash_Fct_Ptr hash_fct = Aleph::dft_hash_fct<Key>,
152 float lower_alpha = hash_default_lower_alpha,
153 float upper_alpha = hash_default_upper_alpha,
154 bool remove_all_buckets =
true,
155 bool with_resize =
true)
156 : GenLhashTable(table_size, Hash_Fct(hash_fct), cmp,
157 lower_alpha, upper_alpha, remove_all_buckets, with_resize)
160 void swap(GenLhashTable & other) noexcept
162 std::swap(hash_fct, other.hash_fct);
163 std::swap(table, other.table);
164 std::swap(len, other.len);
165 std::swap(cmp, other.cmp);
166 std::swap(N, other.N);
167 std::swap(busy_slots_counter, other.busy_slots_counter);
168 std::swap(remove_all_buckets, other.remove_all_buckets);
169 std::swap(with_resize, other.with_resize);
175 for (
int i = 0; i < len; ++i)
176 for (BucketItor itor(table[i]); itor.has_curr(); )
177 delete (
Bucket*) itor.del_ne();
178 busy_slots_counter = N = 0;
184 search_in_bucket_list(
BucketList &
list,
const Key & key)
const noexcept
186 for (BucketItor it(list); it.has_curr(); it.next_ne())
188 Bucket * bucket =
static_cast<Bucket*
>(it.get_curr_ne());
189 if (cmp (key, bucket->
get_key()))
198 Hash_Fct get_hash_fct()
const noexcept {
return hash_fct; }
206 void set_hash_fct(Hash_Fct_Ptr fct) noexcept
208 hash_fct = Hash_Fct(fct);
218 const auto i = hash_fct(bucket->
get_key()) % len;
219 auto & list = table[i];
222 ++busy_slots_counter;
224 if (search_in_bucket_list(list, bucket->
get_key()) !=
nullptr)
230 if (with_resize and current_alpha() >= upper_alpha)
231 resize(next_prime(2*len));
240 const auto i = hash_fct(bucket->
get_key()) % len;
241 auto & list = table[i];
244 ++busy_slots_counter;
246 auto * p = search_in_bucket_list(list, bucket->
get_key());
253 if (with_resize and current_alpha() >= upper_alpha)
254 resize(next_prime(2*len));
263 const auto i = hash_fct(key) % len;
264 return search_in_bucket_list(table[i], key);
276 --busy_slots_counter;
290 remove_bucket(bucket);
292 if (with_resize and current_alpha() < lower_alpha)
293 resize(next_prime(len/2));
305 if (new_size == len or new_size == 0)
310 const size_t old_size = len;
313 busy_slots_counter = N = 0;
315 for (
int i = 0; i < old_size; ++i)
317 for (BucketItor it(old_table[i]); it.has_curr(); )
318 insert((
Bucket*) it.del_ne());
330 if (remove_all_buckets)
340 assert(bucket !=
nullptr);
342 const auto i = hash_fct(bucket->
get_key()) % len;
344 BucketItor itor(table[i]);
351 if (not itor.has_curr())
354 Bucket * node =
static_cast<Bucket*
>(itor.get_curr_ne());
362 const size_t &
capacity() const noexcept {
return len; }
365 const size_t &
size() const noexcept {
return N; }
371 bool is_empty()
const noexcept {
return N == 0; }
383 long curr_index = -1;
385 BucketItor curr_itor;
386 GenLhashTable * hash_table =
nullptr;
389 void locate_next_available_entry_ne() noexcept
393 if (curr_index == hash_table->len - 1)
395 curr_index = hash_table->len;
401 if (not hash_table->table[curr_index].
is_empty())
403 BucketItor itor(hash_table->table[curr_index]);
410 void locate_next_available_entry()
414 if (curr_index == hash_table->len)
415 throw std::overflow_error (
"hash table iterator overflow");
417 if (curr_index == hash_table->len - 1)
419 curr_index = hash_table->len;
425 if (not hash_table->table[curr_index].
is_empty())
427 BucketItor itor(hash_table->table[curr_index]);
434 void locate_next_available_bucket_ne() noexcept
437 if (not curr_itor.has_curr())
438 locate_next_available_entry_ne();
442 void locate_next_available_bucket()
445 if (not curr_itor.has_curr())
446 locate_next_available_entry();
450 void locate_prev_available_entry_ne() noexcept
462 if (not hash_table->table[curr_index].
is_empty())
464 BucketItor itor(hash_table->table[curr_index]);
466 curr_itor.reset_last();
472 void locate_prev_available_entry()
476 if (curr_index == -1)
477 throw std::underflow_error (
"hash table iterator underflow");
487 if (not hash_table->table[curr_index].
is_empty())
489 BucketItor itor(hash_table->table[curr_index]);
491 curr_itor.reset_last();
497 void locate_prev_available_bucket_ne() noexcept
500 if (not curr_itor.has_curr())
501 locate_prev_available_entry_ne();
505 void locate_prev_available_bucket()
508 if (not curr_itor.has_curr())
509 locate_prev_available_entry();
523 : hash_table(&const_cast<GenLhashTable&>(table))
527 locate_next_available_entry();
529 catch (std::overflow_error)
541 locate_next_available_entry();
547 curr_index = hash_table->len;
548 curr_pos = hash_table->N - 1;
549 locate_prev_available_entry();
554 put_itor_at_the_end(*
this);
560 return curr_index >= 0 and curr_index < hash_table->len;
563 Bucket * get_curr_ne() noexcept
565 return static_cast<Bucket*
>(curr_itor.get_curr_ne());
571 if (curr_index == -1)
572 throw std::underflow_error (
"hash table iterator underflow");
574 if (curr_index == hash_table->len)
575 throw std::overflow_error (
"hash table iterator overflow");
577 return static_cast<Bucket*
>(curr_itor.get_curr());
580 long get_pos()
const noexcept {
return curr_pos; }
585 locate_next_available_bucket_ne();
590 if (curr_index == hash_table->len)
591 throw std::overflow_error (
"hash table iterator overflow");
598 locate_prev_available_bucket_ne();
603 if (curr_index == -1)
604 throw std::underflow_error (
"hash table iterator underflow");
605 locate_prev_available_bucket();
610 Bucket * ret_val = get_curr();
612 hash_table->remove_bucket(ret_val);
635 template <
typename Key>
659 template <
typename Key,
class Cmp = Aleph::equal_to<Key>>
660 struct LhashTable :
public GenLhashTable<Key, LhashBucket<Key>, Cmp>
680 template <
typename Key,
class Cmp = Aleph::equal_to<Key> >
Bucket * insert(Bucket *bucket)
Definition: tpl_lhash.H:216
virtual ~GenLhashTable()
Definition: tpl_lhash.H:328
const size_t & get_num_busy_slots() const noexcept
Retorna la cantidad de entradas del arreglo que están ocupadas.
Definition: tpl_lhash.H:369
Iterator() noexcept
Instancia un iterador vacÃo.
Definition: tpl_lhash.H:534
Iterator(const GenLhashTable &table) noexcept
Instancia un iterador sobre la tabla hash table.
Definition: tpl_lhash.H:522
void reset_last() noexcept
Reinicia el iterador sobre la última cubeta.
Definition: tpl_lhash.H:545
T & get_key() noexcept
Definition: tpl_dnode.H:187
virtual ~LhashBucketVtl()
destructor virtual.
Definition: tpl_lhash.H:642
Dnode< T > *& get_next() const noexcept
Return the next node to this
Definition: tpl_dnode.H:53
void set_hash_fct(Hash_Fct fct) noexcept
Set the internal hash function.
Definition: tpl_lhash.H:201
Definition: tpl_lhash.H:636
bool has_curr() const noexcept
Retorna true si el iterador tiene cubeta actual.
Definition: tpl_lhash.H:558
void empty() noexcept
VacÃa la tabla hash; libera memoria de todas las cubetas.
Definition: tpl_lhash.H:173
void prev_ne() noexcept
Retrocede el iterador una cubeta.
Definition: tpl_lhash.H:596
Definition: tpl_lhash.H:77
Bucket * Item_Type
El tipo de elemento que retorna get_curr().
Definition: tpl_lhash.H:519
float current_alpha() const noexcept
return the current table load
Definition: tpl_lhash.H:212
void reset_first() noexcept
Reinicia el iterador sobre la primera cubeta.
Definition: tpl_lhash.H:537
bool is_empty() const noexcept
Return true if this (as header node) is empty.
Definition: dlink.H:192
const size_t & size() const noexcept
Retorna el número de elementos que contiene la tabla.
Definition: tpl_lhash.H:365
Dlink * del() noexcept
Remove this from the list. this must not be a header node.
Definition: dlink.H:389
size_t resize(size_t new_size)
Definition: tpl_lhash.H:301
Definition: tpl_lhash.H:681
Bucket * search_next(Bucket *bucket) const noexcept
Definition: tpl_lhash.H:338
void append(Dlink *node) noexcept
Definition: dlink.H:228
GenLhashTable(size_t table_size=Primes::DefaultPrime, Hash_Fct_Ptr hash_fct=Aleph::dft_hash_fct< Key >, Cmp cmp=Cmp(), float lower_alpha=hash_default_lower_alpha, float upper_alpha=hash_default_upper_alpha, bool remove_all_buckets=true, bool with_resize=true)
Definition: tpl_lhash.H:149
Bucket * search(const Key &key) const noexcept
Definition: tpl_lhash.H:261
Definition: tpl_lhash.H:660
void next_ne() noexcept
Avanza el iterador una cubeta.
Definition: tpl_lhash.H:583
Bucket * get_curr()
Retorna la cubeta actual.
Definition: tpl_lhash.H:569
const size_t & capacity() const noexcept
Retorna el tamaño de la tabla.
Definition: tpl_lhash.H:362
Definition: tpl_lhash.H:379