7 # include <tpl_dynArray.H>
8 # include <tpl_dnode.H>
10 # include <hash-dry.H>
24 using namespace Aleph;
28 # define LINBUCKET_BODY(BUCKETNAME) \
34 BUCKETNAME(const BUCKETNAME & bucket) : Dnode<Key>(bucket) {} \
38 BUCKETNAME(const Key & key) : Dnode<Key>(key) {} \
40 Key & get_key() { return this->get_data(); } \
42 Dlink * get_link() { return &link; } \
44 DLINK_TO_BASE(BUCKETNAME, link);
54 template <
typename Key>
67 template <
typename Key>
103 template <
typename Key,
template <
class>
class BucketType,
116 typedef Key Key_Type;
118 typedef Key Item_Type;
126 static size_t multiply_by_two(
const size_t & n) {
return n << 1; }
128 static size_t divide_by_two(
const size_t & n) {
return n >> 1; }
143 size_t busy_slots_counter;
144 bool remove_all_buckets;
165 size_t call_hash_fct(
const Key & key)
const
167 const size_t hash = (*hash_fct)(key);
168 const size_t i = hash % M;
169 return i < p ? hash % MM : i;
174 for (
float alpha = 1.0*N/MP; alpha >= upper_alpha; alpha = 1.0*N/MP)
176 BucketList * src_list_ptr = table.test(p);
177 if (src_list_ptr != NULL)
178 if (not src_list_ptr->is_empty())
180 BucketList * tgt_list_ptr = NULL;
183 for (BucketItor it(*src_list_ptr); it.has_current(); )
185 Bucket * bucket =
static_cast<Bucket*
>(it.get_current());
189 const Key & key = bucket->get_key();
190 const int i = (*hash_fct)(key) % MM;
194 if (tgt_list_ptr == NULL)
195 tgt_list_ptr = &table.touch(MP);
200 tgt_list_ptr->append(bucket);
203 if (src_list_ptr->is_empty())
204 --busy_slots_counter;
206 ++busy_slots_counter;
215 MM = multiply_by_two(MM);
222 for (
float alpha = (1.0*N)/MP; alpha <= lower_alpha and MP > len;
229 M = divide_by_two(M);
236 if (MP < table.size())
238 BucketList * src_list_ptr = table.test(MP);
239 if (src_list_ptr != NULL)
241 if (not src_list_ptr->is_empty())
243 BucketList & tgt_list = table.touch(p);
244 tgt_list.concat_list(src_list_ptr);
245 --busy_slots_counter;
261 Hash_Fct get_hash_fct()
const {
return hash_fct; }
263 const Cmp & get_compare()
const {
return cmp; }
291 const size_t & __len = Primes::DefaultPrime,
292 const float & __lower_alpha = hash_default_lower_alpha,
293 const float & __upper_alpha = hash_default_upper_alpha,
294 const bool __remove_all_buckets =
true,
295 const bool __with_resize =
true)
296 throw(std::exception, std::length_error, std::domain_error,
297 std::bad_alloc, std::overflow_error)
298 : table(__len), hash_fct(__hash_fct), M(__len), N(0),
299 busy_slots_counter(0), remove_all_buckets(__remove_all_buckets),
300 upper_alpha(__upper_alpha), lower_alpha(__lower_alpha),
301 p(0), l(0), MP(M), MM(multiply_by_two(M)), len(__len)
304 std::length_error(
"table's length is zero");
306 if (MM > table.max_size())
307 throw std::length_error(
"table's length too big");
309 if (upper_alpha <= lower_alpha)
310 throw std::domain_error(
"lower alpha is greater than lower alpha");
315 std::swap(table, other.table);
316 std::swap(hash_fct, other.hash_fct);
317 std::swap(M, other.M);
318 std::swap(N, other.N);
319 std::swap(busy_slots_counter, other.busy_slots_counter);
320 std::swap(remove_all_buckets, other.remove_all_buckets);
321 std::swap(upper_alpha, other.upper_alpha);
322 std::swap(lower_alpha, other.lower_alpha);
323 std::swap(p, other.p);
324 std::swap(l, other.l);
325 std::swap(MP, other.MP);
326 std::swap(MM, other.MM);
327 std::swap(len, other.len);
352 bucket->get_link()->del();
357 MM = multiply_by_two(M);
364 if (remove_all_buckets)
370 Bucket * search_in_bucket_list(BucketList *
list,
const Key & key)
const
372 for (BucketItor it(*list); it.has_curr(); it.next())
374 Bucket * bucket =
static_cast<Bucket*
>(it.get_current());
375 if (cmp (key, bucket->get_key()))
389 const int i = call_hash_fct(key);
397 return search_in_bucket_list(list, key);
401 const size_t &
size()
const {
return N; }
410 const size_t &
busy_slots()
const {
return busy_slots_counter; }
420 const int i = call_hash_fct(bucket->get_key());
423 ++busy_slots_counter;
425 if (search_in_bucket_list(&list, bucket->get_key()) != NULL)
429 entries_list.
append(bucket->get_link());
448 I(
search(bucket->get_key()) == bucket);
450 Bucket * next =
static_cast<Bucket*
>(bucket->get_next());
454 if (next->is_empty())
455 --busy_slots_counter;
469 bucket->get_link()->
del();
470 return remove_bucket(bucket);
475 for (
int i = 0; i < MP; ++i)
477 cout <<
"table[" << i <<
"] = [ ";
481 BucketList & list = table.access(i);
483 if (not list.is_empty())
484 for (BucketItor it(list); it.has_current(); it.next())
486 Bucket * bucket =
static_cast<Bucket*
>(it.get_current());
487 const Key & key = bucket->get_key();
528 return Bucket::dlink_to_base(this->Dlink::Iterator::get_curr());
534 return (
Bucket *) hash_table->remove_bucket(bucket);
559 template <
typename Key,
class Cmp = Aleph::equal_to<Key>>
586 template <
typename Key,
class Cmp = Aleph::equal_to<Key>>
607 # endif // TPL_LINHASH_H
size_t(* Hash_Fct)(const Key &)
Definition: tpl_linHash.H:111
Bucket * Item_Type
El tipo de elemento que retorna get_curr().
Definition: tpl_linHash.H:509
bool is_empty() const
return true is table is empty
Definition: tpl_linHash.H:404
Definition: tpl_linHash.H:68
GenLinearHashTable Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_linHash.H:506
Dlink * remove_first()
Elimina el primer elemento de this.
Definition: dlink.H:325
Iterador sobre enlaces.
Definition: dlink.H:437
Definition: tpl_linHash.H:587
Bucket * insert(Bucket *bucket)
Definition: tpl_linHash.H:418
BucketType< Key > Bucket
El tipo de cubeta.
Definition: tpl_linHash.H:114
Definition: tpl_linHash.H:55
const size_t & expansions() const
Definition: tpl_linHash.H:414
Iterator(const GenLinearHashTable &table)
Instancia un iterador sobre la tabla hash table.
Definition: tpl_linHash.H:512
const size_t & capacity() const
Retorna el tamaño de la tabla.
Definition: tpl_linHash.H:407
Definition: tpl_linHash.H:105
Iterator()
Instancia un iterador vacío.
Definition: tpl_linHash.H:520
const size_t & size() const
Retorna la cantidad de elementos que tiene la tabla.
Definition: tpl_linHash.H:401
void empty()
Definition: tpl_linHash.H:346
Bucket * get_curr()
Retorna la cubeta actual.
Definition: tpl_linHash.H:526
Definition: tpl_linHash.H:497
const size_t & busy_slots() const
Retorna la cantidad de entradas vacía que tiene la tabla.
Definition: tpl_linHash.H:410
size_t resize(size_t)
Provided for generic programming compatibility.
Definition: tpl_linHash.H:437
Definition: tpl_dynArray.H:70
GenLinearHashTable(Hash_Fct __hash_fct=Aleph::dft_hash_fct< Key >, const size_t &__len=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_linHash.H:290
void append(Dlink *node)
Definition: dlink.H:166
void set_hash_fct(Hash_Fct fct)
Set the internal hash function.
Definition: tpl_linHash.H:256
Definition: ahFunction.H:115
bool is_empty() const
retorna true si this está vacía
Definition: dlink.H:127
float current_alpha() const
return the current table load
Definition: tpl_linHash.H:266
void del()
Elimina this de su contexto en una lista.
Definition: dlink.H:278
Definition: tpl_linHash.H:560
Bucket * search(const Key &key) const
Definition: tpl_linHash.H:387
Nodo perteneciente a lista doblemente enlazada circular.
Definition: tpl_dnode.H:19
Dlink * del()
Definition: dlink.H:612