99template <
class HashTbl,
typename Key>
146 for (
long i = 0, c = 0; c <
other.N; ++i)
148 auto & bucket =
other.table[i];
149 if (bucket.status != HashTbl::BUSY)
168 for (
long i = 0; i <
me()->len; ++i)
169 me()->table[i].reset();
183 if (
me()->with_resize
and me()->
N >=
me()->len - 1)
206 auto bucket =
me()->allocate_bucket(key);
207 if (bucket ==
nullptr)
212 return me()->test_resize(bucket, key);
234 auto bucket =
me()->allocate_bucket(key);
235 if (bucket ==
nullptr)
238 std::swap(bucket->key, key);
240 return me()->test_resize(bucket, bucket->key);
262 auto r =
me()->hard_allocate_bucket(key);
264 if (bucket ==
nullptr)
271 return me()->test_resize(bucket, bucket->key);
294 auto r =
me()->hard_allocate_bucket(key);
296 if (bucket ==
nullptr)
301 std::swap(bucket->key, key);
303 return me()->test_resize(bucket, bucket->key);
335 auto r =
me()->hard_allocate_bucket(key);
337 if (bucket ==
nullptr)
338 return {
nullptr,
false };
340 return { &bucket->key,
true };
343 auto key_ptr =
me()->test_resize(bucket, bucket->key);
345 return { key_ptr,
false };
368 auto r =
me()->hard_allocate_bucket(key);
370 if (bucket ==
nullptr)
371 return {
nullptr,
false };
373 return { &bucket->key,
true };
375 std::swap(bucket->key, key);
376 auto key_ptr =
me()->test_resize(bucket, bucket->key);
378 return { key_ptr,
false };
404 return this->
insert(std::move(key));
416 return const_me()->search(key) !=
nullptr;
440 auto key_ptr =
me()->search(key);
442 <<
"Key not found in hash";
504 auto bucket = HashTbl::key_to_bucket(key);
505 me()->deallocate_bucket(bucket);
533 <<
"New size is not enough for current number of entries";
536 typename HashTbl::Bucket *
old_table =
me()->table;
546 if (
old_table[i].status == HashTbl::BUSY)
549 auto bucket =
me()->allocate_bucket(key);
550 std::swap(bucket->key, key);
571 auto new_table =
new typename HashTbl::Bucket [
me()->len];
579 for (
int i = 0, c = 0; i <
me()->len
and c <
old_N; ++i)
580 if (
old_table[i].status == HashTbl::BUSY)
583 auto bucket =
me()->allocate_bucket(key);
584 std::swap(bucket->key, key);
603 delete []
me()->table;
606 me()->table =
new typename HashTbl::Bucket [
me()->len];
692 <<
"Iterator next() overflow";
702 <<
"Iterator next() underflow";
796 <<
"O hash::Iterator next() overflow";
799 <<
"O hash::Iterator next() underflow";
878 <<
"Overflow in del() of iterator";
940 std::cout <<
"M = " << this->
capacity() <<
'\n'
941 <<
"N = " << this->
size() <<
'\n'
942 <<
"busy slots = " << stats.
num_busy <<
'\n'
944 <<
"empty slots = " << stats.
num_empty <<
'\n'
945 <<
"alpha = " <<
const_me()->current_alpha() <<
'\n'
946 <<
"max length = " << stats.
max_len <<
'\n';
947 for (
size_t i = 0; i < stats.
lens.
size(); ++i)
948 std::cout <<
" " << i <<
" = " << stats.
lens(i) <<
'\n';
983template <
class HashTbl>
1043 for (
int i = 0; i <
const_me()->capacity(); ++i)
1047 for (
typename HashTbl::BucketItor it(list); it.has_curr();
1054 float avg = 0,
sum = 0;
1055 for (
size_t i = 0; i < lens.
size(); ++i)
1063 for (
size_t i = 0; i < lens.
size(); ++i)
1088 std::cout <<
"M = " <<
const_me()->capacity() <<
'\n'
1089 <<
"N = " <<
const_me()->size() <<
'\n'
1091 <<
"Average = " <<
stats.
avg <<
'\n'
1096 std::cout <<
" " << i <<
" = " <<
stats.
lens(i) <<
'\n';
1110 <<
"upper_alpha lower than lower_alpha";
1126 <<
"lower_alpha greater than upper_alpha";
Exception handling system with formatted messages for Aleph-w.
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Core header for the Aleph-w library.
void put_itor_at_the_end(Itor &it) noexcept
Doubly linked circular list node.
T & touch(const size_t i)
Touch the entry i.
size_t size() const noexcept
Return the current dimension of array.
bool exist(const size_t i) const
Return true if the i-th entry is accessible.
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
Insert a new item by copy.
size_t size() const noexcept
Count the number of elements of the list.
CRTP mixin providing statistics and configuration for chained hash tables.
constexpr float get_upper_alpha() const noexcept
Returns the upper load factor threshold.
float lower_alpha
Lower load factor threshold for shrinking.
HashTbl * me()
Returns a pointer to the derived class (CRTP pattern).
float upper_alpha
Upper load factor threshold for growing.
Stats stats() const
Computes statistics about chain length distribution.
static void update_stat_len(DynArray< size_t > &lens, size_t i)
Updates chain length histogram.
size_t busy_slots_counter
Number of buckets with at least one entry.
void set_upper_alpha(float __upper_alpha)
Sets the upper load factor threshold.
size_t N
Total number of entries.
void print_stats(const Stats &stats) const
Prints statistics to standard output.
void set_lower_alpha(float __lower_alpha)
Sets the lower load factor threshold.
const HashTbl * const_me() const
Returns a const pointer to the derived class (CRTP pattern).
constexpr float get_lower_alpha() const noexcept
Returns the lower load factor threshold.
Bidirectional iterator for traversing hash table entries.
Key & get_curr()
Returns a reference to the current entry with bounds checking.
Iterator() noexcept=default
Default constructor creates an "end" iterator.
bool check() const noexcept
Validates iterator state (debug only).
bool has_curr() const noexcept
Checks if the iterator is at a valid position.
constexpr long get_pos() const noexcept
Returns the current logical position.
const Key & get_curr() const
Returns a const reference to the current entry with bounds checking.
void del()
Deletes the current entry and advances to the next.
void end() noexcept
Positions the iterator at the end (past-the-last element).
HashTbl * table_ptr
Pointer to the hash table being iterated.
void prev()
Moves to the previous entry with bounds checking.
void next()
Advances to the next entry with bounds checking.
long curr_idx
Current bucket index.
const Key & get_curr_ne() const noexcept
Returns a const reference to the current entry without checking.
void locate_next_available_entry()
Advances to next entry with bounds checking.
void prev_ne()
Moves to the previous entry without bounds checking.
void locate_prev_available_entry_ne()
Moves to previous entry without bounds checking.
Key & get_curr_ne() noexcept
Returns a reference to the current entry without checking.
void reset_first() noexcept
Positions the iterator at the first entry.
void reset_last() noexcept
Positions the iterator at the last entry.
void locate_prev_available_entry()
Moves to previous entry with bounds checking.
long ordinal
Logical position (0-based count of visited entries).
void next_ne() noexcept
Advances to the next entry without bounds checking.
void locate_next_available_entry_ne() noexcept
Advances to next entry without bounds checking.
constexpr bool is_last() const noexcept
Checks if the iterator is at the last entry.
CRTP mixin providing common operations for open addressing hash tables.
HashTbl * me()
Returns a pointer to the derived class (CRTP pattern).
Key * append(const Key &key)
Alias for insert() (copy version).
std::pair< Key *, bool > contains_or_insert(const Key &key)
Searches for a key, inserting if not found, with existence flag (copy version).
constexpr size_t size() const noexcept
Returns the number of entries in the table.
std::pair< Key *, bool > contains_or_insert(Key &&key)
Searches for a key, inserting if not found, with existence flag (move version).
Key * search_or_insert(const Key &key)
Searches for a key, inserting it if not found (copy version).
constexpr size_t capacity() const noexcept
Returns the current capacity of the table.
Key * search_or_insert(Key &&key)
Searches for a key, inserting it if not found (move version).
size_t resize(size_t new_size)
Resizes the hash table to a new capacity.
void clean_table()
Removes all entries from the table without deallocating storage.
constexpr float get_upper_alpha() const noexcept
Returns the upper load factor threshold for automatic growing.
const Key & find(const Key &key) const
Finds a key and returns a const reference to it.
void empty()
Clears all entries and resets to default capacity.
constexpr bool is_empty() const noexcept
Checks if the table is empty.
void copy_from_table(const HashTbl &other)
Copies all entries from another hash table.
void print_stats(const Stats &stats) const
Prints statistics to standard output.
void remove_ptr(Key *key)
Removes an entry by pointer.
DynList< Key > keys() const
Returns a list containing all keys in the table.
Key * insert(Key &&key)
Inserts a key into the hash table (move version).
const Key & operator[](const Key &key) const
Subscript operator for const access.
constexpr float get_lower_alpha() const noexcept
Returns the lower load factor threshold for automatic shrinking.
Key * insert(const Key &key)
Inserts a key into the hash table (copy version).
constexpr bool has(const Key &key) const noexcept
Checks if a key exists in the table.
constexpr bool contains(const Key &key) const noexcept
Alias for has().
Key & find(const Key &key)
Finds a key and returns a reference to it.
void rehash()
Rebuilds the hash table with the same capacity.
void check_resize_before_insert()
Checks if resize is needed before inserting and performs it.
Key * append(Key &&key)
Alias for insert() (move version).
auto items() const
Alias for keys().
constexpr float current_alpha() const noexcept
Returns the current load factor (alpha).
const HashTbl * const_me() const
Returns a const pointer to the derived class (CRTP pattern).
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_sqrt_function > > sqrt(const __gmp_expr< T, U > &expr)
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_min_function > > min(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
const unsigned long DefaultPrime
Default prime number used when no specific size is requested.
size_t next_prime(unsigned long n)
Find the smallest prime number >= n from the database.
Statistics about chain length distribution.
DynArray< size_t > lens
Distribution: lens[i] = number of chains with length i.
float avg
Average chain length.
float var
Variance of chain lengths.
Statistics about hash table performance.
size_t num_deleted
Number of buckets marked as deleted.
size_t num_empty
Number of empty buckets.
DynArray< size_t > lens
Distribution of probe sequence lengths.
float avg
Average probe sequence length.
Stats()
Default constructor initializing max_len to minimum.
size_t num_busy
Number of occupied buckets.
float var
Variance of probe sequence lengths.
size_t max_len
Maximum probe sequence length.
Lazy and scalable dynamic array implementation.