8 # include <tpl_dynArray.H> 9 # include <tpl_dnode.H> 12 # include <hash-fct.H> 13 # include <hash-dry.H> 27 using namespace Aleph;
31 # define LINBUCKET_BODY(BUCKETNAME) \ 37 BUCKETNAME(const BUCKETNAME & bucket) \ 38 noexcept(std::is_nothrow_constructible<Dnode<Key>>::value) \ 39 : Dnode<Key>(bucket) {} \ 41 BUCKETNAME() noexcept(std::is_nothrow_constructible<Key>::value) {} \ 43 BUCKETNAME(const Key & key) noexcept(noexcept(Dnode<Key>(key))) \ 44 : Dnode<Key>(key) {} \ 46 Key & get_key() noexcept { return this->get_data(); } \ 48 Dlink * get_link() noexcept { return &link; } \ 50 DLINK_TO_BASE(BUCKETNAME, link); 60 template <
typename Key>
73 template <
typename Key>
108 template <
typename Key,
template <
class>
class BucketType,
109 class Cmp = Aleph::equal_to<Key>>
111 :
public HashStats<GenLinearHashTable<Key, BucketType, Cmp>>
113 friend class HashStats<GenLinearHashTable<Key, BucketType, Cmp>>;
119 using Hash_Fct = std::function<size_t(const Key &)>;
120 using Hash_Fct_Ptr = size_t (*) (
const Key &);
125 using Key_Type = Key;
127 using Item_Type = Key;
135 static size_t multiply_by_two(
const size_t & n) noexcept {
return n << 1; }
137 static size_t divide_by_two(
const size_t & n) noexcept {
return n >> 1; }
151 size_t busy_slots_counter;
152 bool remove_all_buckets;
173 size_t call_hash_fct(
const Key & key)
const 174 noexcept(noexcept(hash_fct(key)))
176 const auto hash = hash_fct(key);
177 const auto i = hash % M;
178 return i < p ? hash % MM : i;
183 for (
float alpha = 1.0*N/MP; alpha >= upper_alpha; alpha = 1.0*N/MP)
186 if (src_list_ptr !=
nullptr)
192 for (BucketItor it(*src_list_ptr); it.has_curr(); )
194 Bucket * bucket =
static_cast<Bucket*
>(it.get_curr_ne());
198 const Key & key = bucket->
get_key();
199 const int i = hash_fct(key) % MM;
203 if (tgt_list_ptr ==
nullptr)
204 tgt_list_ptr = &table.
touch(MP);
209 tgt_list_ptr->
append(bucket);
213 --busy_slots_counter;
215 ++busy_slots_counter;
224 MM = multiply_by_two(MM);
229 void contract() noexcept
231 for (
float alpha = (1.0*N)/MP; alpha <= lower_alpha and MP > len;
238 M = divide_by_two(M);
245 if (MP < table.
size())
248 if (src_list_ptr !=
nullptr)
254 --busy_slots_counter;
270 void set_hash_fct(Hash_Fct_Ptr fct) noexcept
275 Hash_Fct get_hash_fct()
const noexcept {
return hash_fct; }
277 Cmp & get_compare() noexcept {
return cmp; }
279 const Cmp & get_compare()
const noexcept {
return cmp; }
286 GenLinearHashTable(
size_t __len,
Hash_Fct __hash_fct, Cmp __cmp,
287 float __lower_alpha,
float __upper_alpha,
288 bool __remove_all_buckets,
bool )
289 : table(__len), hash_fct(__hash_fct), cmp(__cmp), M(__len), N(0),
290 busy_slots_counter(0), remove_all_buckets(__remove_all_buckets),
291 upper_alpha(__upper_alpha), lower_alpha(__lower_alpha),
292 p(0), l(0), MP(M), MM(multiply_by_two(M)), len(__len)
295 std::length_error(
"table's length is zero");
298 throw std::length_error(
"table's length too big");
300 if (upper_alpha <= lower_alpha)
301 throw std::domain_error(
"lower alpha is greater than lower alpha");
329 Hash_Fct_Ptr hash_fct = Aleph::dft_hash_fct<Key>,
331 float lower_alpha = hash_default_lower_alpha,
332 float upper_alpha = hash_default_upper_alpha,
333 bool remove_all_buckets =
true,
334 bool with_resize =
true)
335 : GenLinearHashTable(len,
Hash_Fct(hash_fct), cmp,
336 lower_alpha, upper_alpha,
337 remove_all_buckets, with_resize) {}
339 void swap(GenLinearHashTable & other) noexcept
341 std::swap(table, other.table);
342 std::swap(hash_fct, other.hash_fct);
343 std::swap(M, other.M);
344 std::swap(N, other.N);
345 std::swap(busy_slots_counter, other.busy_slots_counter);
346 std::swap(remove_all_buckets, other.remove_all_buckets);
347 std::swap(upper_alpha, other.upper_alpha);
348 std::swap(lower_alpha, other.lower_alpha);
349 std::swap(p, other.p);
350 std::swap(l, other.l);
351 std::swap(MP, other.MP);
352 std::swap(MM, other.MM);
353 std::swap(len, other.len);
370 void empty() noexcept
378 bucket->get_link()->del();
383 MM = multiply_by_two(M);
388 ~GenLinearHashTable()
390 if (remove_all_buckets)
397 search_in_bucket_list(
BucketList *
list,
const Key & key)
const noexcept
399 for (BucketItor it(*list); it.has_curr(); it.next_ne())
401 Bucket * bucket =
static_cast<Bucket*
>(it.get_curr_ne());
402 if (cmp (key, bucket->get_key()))
416 auto i = call_hash_fct(key);
424 return search_in_bucket_list(list, key);
428 const size_t &
size() const noexcept {
return N; }
434 const size_t &
capacity() const noexcept {
return MP; }
437 const size_t &
busy_slots() const noexcept {
return busy_slots_counter; }
447 const int i = call_hash_fct(bucket->get_key());
450 ++busy_slots_counter;
452 if (search_in_bucket_list(&list, bucket->get_key()) !=
nullptr)
456 entries_list.
append(bucket->get_link());
465 const int i = call_hash_fct(bucket->get_key());
468 ++busy_slots_counter;
470 Bucket * p = search_in_bucket_list(&list, bucket->get_key());
475 entries_list.
append(bucket->get_link());
483 size_t resize(
size_t) noexcept {
return MP; }
493 assert(bucket !=
nullptr);
494 assert(search(bucket->get_key()) == bucket);
496 Bucket * next =
static_cast<Bucket*
>(bucket->get_next());
500 if (next->is_empty())
501 --busy_slots_counter;
515 bucket->get_link()->del();
516 return remove_bucket(bucket);
521 for (
int i = 0; i < MP; ++i)
523 cout <<
"table[" << i <<
"] = [ ";
530 for (BucketItor it(list); it.has_curr(); it.next_ne())
532 Bucket * bucket =
static_cast<Bucket*
>(it.get_curr_ne());
533 const Key & key = bucket->get_key();
545 GenLinearHashTable * hash_table =
nullptr;
551 using Set_Type = GenLinearHashTable;
554 using Item_Type =
Bucket *;
557 Iterator(
const GenLinearHashTable & table) noexcept
559 hash_table(& const_cast<GenLinearHashTable &>(table))
565 Iterator() noexcept { }
567 Bucket * get_curr_ne() noexcept
581 return (
Bucket *) hash_table->remove_bucket(bucket);
584 void next_ne() noexcept
602 long get_pos()
const noexcept {
return pos; }
626 template <
typename Key,
class Cmp = Aleph::equal_to<Key>>
649 template <
typename Key,
class Cmp = Aleph::equal_to<Key>>
665 # endif // TPL_LINHASH_H Definition: tpl_linHash.H:74
void next_ne() noexcept
Definition: dlink.H:715
Dnode & swap(Dnode &p) noexcept(noexcept(std::swap(data, p.data)))
Swap this with p
Definition: tpl_dnode.H:136
T & access(const size_t i) const noexcept
Definition: tpl_dynArray.H:874
Dlink * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition: dlink.H:670
T & touch(const size_t i)
Definition: tpl_dynArray.H:958
size_t max_size() const noexcept
Definition: tpl_dynArray.H:647
Dlink * remove_first_ne() noexcept
Definition: dlink.H:449
T & get_key() noexcept
Definition: tpl_dnode.H:187
const size_t & busy_slots() const noexcept
Retorna la cantidad de entradas vacÃa que tiene la tabla.
Definition: tpl_linHash.H:437
const size_t & size() const noexcept
Retorna la cantidad de elementos que tiene la tabla.
Definition: tpl_linHash.H:428
size_t resize(size_t) noexcept
Provided for generic programming compatibility.
Definition: tpl_linHash.H:483
bool exist(const size_t i) const
Definition: tpl_dynArray.H:895
Bucket * insert(Bucket *bucket)
Definition: tpl_linHash.H:445
const size_t & capacity() const noexcept
Retorna el tamaño de la tabla.
Definition: tpl_linHash.H:434
float current_alpha() const noexcept
return the current table load
Definition: tpl_linHash.H:282
Definition: tpl_linHash.H:61
GenLinearHashTable(size_t len=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_linHash.H:328
T * test(const size_t i) const noexcept
Definition: tpl_dynArray.H:927
Definition: tpl_linHash.H:110
BucketType< Key > Bucket
El tipo de cubeta.
Definition: tpl_linHash.H:123
Bucket * search(const Key &key) const noexcept
Definition: tpl_linHash.H:414
bool is_empty() const noexcept
return true is table is empty
Definition: tpl_linHash.H:431
std::function< size_t(const Key &)> Hash_Fct
Definition: tpl_linHash.H:119
Dlink * get_curr() const
Definition: dlink.H:681
bool is_empty() const noexcept
Return true if this (as header node) is empty.
Definition: dlink.H:192
Dlink * del() noexcept
Remove this from the list. this must not be a header node.
Definition: dlink.H:389
void prev()
Definition: dlink.H:706
void set_hash_fct(Hash_Fct fct) noexcept
Set the internal hash function.
Definition: tpl_linHash.H:265
size_t size() const noexcept
Definition: tpl_dynArray.H:641
Definition: tpl_dynArray.H:159
void append(Dlink *node) noexcept
Definition: dlink.H:228
void concat_list(Dlink *head) noexcept
Definition: dlink.H:362
void next()
Definition: dlink.H:721
const size_t & expansions() const noexcept
Definition: tpl_linHash.H:441
Dlink * del()
Definition: dlink.H:741