8 # include <tpl_dlist.H>
9 # include <tpl_dynArray.H>
10 # include <hash-dry.H>
22 using namespace Primes;
24 using namespace Aleph;
47 template <
typename Key,
class BucketType,
class Cmp>
52 typedef BucketType Bucket;
54 typedef size_t (*Hash_Fct)(
const Key &);
58 typedef Key Item_Type;
81 size_t busy_slots_counter;
82 bool remove_all_buckets;
96 size_t table_size = Primes::DefaultPrime,
97 const float & __lower_alpha = hash_default_lower_alpha,
98 const float & __upper_alpha = hash_default_upper_alpha,
99 const bool __remove_all_buckets =
true,
100 const bool __with_resize =
true)
101 throw(std::exception, std::bad_alloc)
102 : hash_fct(__hash_fct), table(NULL),
103 len(Primes::next_prime(table_size)),
104 lower_alpha(__lower_alpha), upper_alpha(__upper_alpha),
105 N(0), busy_slots_counter(0), remove_all_buckets(__remove_all_buckets),
106 with_resize(__with_resize)
113 std::swap(hash_fct, other.hash_fct);
114 std::swap(table, other.table);
115 std::swap(len, other.len);
116 std::swap(N, other.N);
117 std::swap(busy_slots_counter, other.busy_slots_counter);
118 std::swap(remove_all_buckets, other.remove_all_buckets);
119 std::swap(with_resize, other.with_resize);
125 for (
int i = 0; i < len; ++i)
126 for (BucketItor itor(table[i]); itor.has_curr(); )
127 delete (
Bucket*) itor.del();
128 busy_slots_counter = N = 0;
133 Bucket * search_in_bucket_list(BucketList &
list,
const Key & key)
const
135 for (BucketItor it(list); it.has_curr(); it.next())
137 Bucket * bucket =
static_cast<Bucket*
>(it.get_current());
138 if (Cmp () (key, bucket->get_key()))
147 Hash_Fct get_hash_fct()
const {
return hash_fct; }
162 const size_t i = (*hash_fct)(bucket->
get_key()) % len;
166 ++busy_slots_counter;
168 if (search_in_bucket_list(list, bucket->
get_key()) != NULL)
174 if (with_resize and current_alpha() >= upper_alpha)
175 resize(next_prime(2*len));
184 const size_t i = (*hash_fct)(key) % len;
185 return search_in_bucket_list(table[i], key);
192 Bucket * remove_bucket(Bucket * bucket)
194 Bucket * next =
static_cast<Bucket*
>(bucket->get_next());
196 if (next->is_empty())
197 --busy_slots_counter;
211 remove_bucket(bucket);
213 if (with_resize and current_alpha() < lower_alpha)
214 resize(next_prime(len/2));
222 size_t resize(
size_t new_size)
throw(std::exception, std::bad_alloc)
226 if (new_size == len or new_size == 0)
231 const size_t old_size = len;
234 busy_slots_counter = N = 0;
236 for (
int i = 0; i < old_size; ++i)
238 for (BucketItor it(old_table[i]); it.has_curr(); )
239 insert((
Bucket*) it.del());
251 if (remove_all_buckets)
263 const size_t i = (*hash_fct)(bucket->
get_key()) % len;
265 BucketItor itor(table[i]);
272 if (not itor.has_curr())
286 const size_t &
size()
const {
return N; }
291 bool is_empty()
const {
return N == 0; }
304 BucketItor curr_itor;
308 void locate_next_available_entry()
312 if (curr_index == hash_table->len)
313 throw std::overflow_error (
"hash table iterator overflow");
315 if (curr_index == hash_table->len - 1)
317 curr_index = hash_table->len;
323 if (not hash_table->table[curr_index].is_empty())
325 BucketItor itor(hash_table->table[curr_index]);
332 void locate_next_available_bucket()
336 if (not curr_itor.has_curr())
337 locate_next_available_entry();
340 void locate_prev_available_entry()
344 if (curr_index == -1)
345 throw std::underflow_error (
"hash table iterator underflow");
355 if (not hash_table->table[curr_index].is_empty())
357 BucketItor itor(hash_table->table[curr_index]);
359 curr_itor.reset_last();
365 void locate_prev_available_bucket()
369 if (not curr_itor.has_curr())
370 locate_prev_available_entry();
383 : curr_index(-1), hash_table(&const_cast<
GenLhashTable&>(table))
387 locate_next_available_entry();
389 catch (std::overflow_error)
404 locate_next_available_entry();
410 curr_index = hash_table->len;
412 locate_prev_available_entry();
418 return curr_index >= 0 and curr_index < hash_table->len;
423 throw(std::exception, std::overflow_error, std::underflow_error)
425 if (curr_index == -1)
426 throw std::underflow_error (
"hash table iterator underflow");
428 if (curr_index == hash_table->len)
429 throw std::overflow_error (
"hash table iterator overflow");
431 return static_cast<Bucket*
>(curr_itor.get_curr());
437 if (curr_index == hash_table->len)
438 throw std::overflow_error (
"hash table iterator overflow");
440 locate_next_available_bucket();
446 if (curr_index == -1)
447 throw std::underflow_error (
"hash table iterator underflow");
449 locate_prev_available_bucket();
454 Bucket * ret_val = get_curr();
456 hash_table->remove_bucket(ret_val);
471 template <
typename Key>
496 template <
typename Key>
530 template <
typename Key,
class Cmp = Aleph::equal_to<Key> >
554 template <
typename Key,
class Cmp = Aleph::equal_to<Key> >
const size_t & size() const
Retorna el número de elementos que contiene la tabla.
Definition: tpl_lhash.H:286
Bucket * insert(Bucket *bucket)
Definition: tpl_lhash.H:160
const size_t & capacity() const
Retorna el tamaño de la tabla.
Definition: tpl_lhash.H:283
virtual ~GenLhashTable()
Definition: tpl_lhash.H:249
LhashBucketVtl()
Instancia una cubeta vacía; valor de clave indefinido.
Definition: tpl_lhash.H:504
void empty()
Vacía la tabla hash; libera memoria de todas las cubetas.
Definition: tpl_lhash.H:123
LhashBucket()
Instancia una cubeta vacía; valor de clave indefinido.
Definition: tpl_lhash.H:480
LhashBucket(const Key &key)
Instancia una cubeta con clave key.
Definition: tpl_lhash.H:483
Bucket * search(const Key &key) const
Definition: tpl_lhash.H:182
Definition: tpl_lhash.H:497
Bucket * Item_Type
El tipo de elemento que retorna get_curr().
Definition: tpl_lhash.H:379
Definition: tpl_lhash.H:48
LhashBucket(const LhashBucket &bucket)
Instancia una cubeta copia de otra.
Definition: tpl_lhash.H:477
Definition: tpl_lhash.H:531
Definition: tpl_lhash.H:555
GenLhashTable(Hash_Fct __hash_fct, size_t table_size=Primes::DefaultPrime, const float &__lower_alpha=hash_default_lower_alpha, const float &__upper_alpha=hash_default_upper_alpha, const bool __remove_all_buckets=true, const bool __with_resize=true)
Definition: tpl_lhash.H:95
Iterator()
Instancia un iterador vacío.
Definition: tpl_lhash.H:394
void prev()
Retrocede el iterador una cubeta.
Definition: tpl_lhash.H:444
void reset_first()
Reinicia el iterador sobre la primera cubeta.
Definition: tpl_lhash.H:400
Bucket * search_next(Bucket *bucket) const
Definition: tpl_lhash.H:259
void reset_last()
Reinicia el iterador sobre la última cubeta.
Definition: tpl_lhash.H:408
GenLhashTable Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_lhash.H:376
Definition: tpl_lhash.H:472
size_t resize(size_t new_size)
Definition: tpl_lhash.H:222
LhashBucketVtl(const Key &key)
Instancia una cubeta con clave key.
Definition: tpl_lhash.H:510
virtual ~LhashBucketVtl()
destructor virtual.
Definition: tpl_lhash.H:507
LhashBucketVtl(const LhashBucketVtl &bucket)
Instancia una cubeta copia de otra.
Definition: tpl_lhash.H:501
const size_t & get_num_busy_slots() const
Retorna la cantidad de entradas del arreglo que están ocupadas.
Definition: tpl_lhash.H:289
Key & get_key()
Retorna la clave de indización de la cubeta.
Definition: tpl_lhash.H:486
Iterator(const GenLhashTable &table)
Instancia un iterador sobre la tabla hash table.
Definition: tpl_lhash.H:382
void append(Dlink *node)
Definition: dlink.H:166
void set_hash_fct(Hash_Fct fct)
Set the internal hash function.
Definition: tpl_lhash.H:150
Bucket * get_curr()
Retorna la cubeta actual.
Definition: tpl_lhash.H:422
float current_alpha() const
return the current table load
Definition: tpl_lhash.H:156
void next()
Avanza el iterador una cubeta.
Definition: tpl_lhash.H:435
Key & get_key()
Retorna la clave de indización de la cubeta.
Definition: tpl_lhash.H:513
bool has_curr() const
Retorna true si el iterador tiene cubeta actual.
Definition: tpl_lhash.H:416
Definition: tpl_lhash.H:299