54 template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC = allocator<K_TYPE>,
typename HASH = hash<K_TYPE>>
82 explicit hashNode(
const K_TYPE& key = K_TYPE{},
const V_TYPE& value = V_TYPE{},
hashNode* next =
nullptr);
113 const K_TYPE&
getKey()
const;
231 389, 769, 1543, 3079, 6151,
232 12289, 24593, 49157, 98317, 196613,
234 393241, 786433, 1572869, 3145739, 6291469,
235 12582917, 25165843, 50331653, 100663319, 201326611,
237 402653189, 805306457, 1610612741, 3221225473, 4294967291
314 [[nodiscard]]
bool hasNext()
const;
347 [[nodiscard]]
bool isValid()
const;
386 hashNode*
createNode(
const K_TYPE& key = K_TYPE{},
const V_TYPE& value = V_TYPE{}, hashNode* next =
nullptr)
const;
413 hashNode*
getBucket(
const K_TYPE& key)
const;
472 bool modify(
const K_TYPE& key,
const V_TYPE& value);
481 bool insert(
const K_TYPE& key,
const V_TYPE& value);
489 bool erase(
const K_TYPE& key);
499template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
501 : data_({key, value}), next_(next) {}
503template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
508template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
513 this->data_ = other.data_;
514 this->next_ = other.next_;
518template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
524template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
530template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
532 return this->
getVal().first();
535template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
537 return this->
getVal().second();
540template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
542 return this->
getVal().second();
545template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
550template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
552 this->data_.template
set<1>(value);
555template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
561template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
567template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
569 this->next_ = new_next;
572template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
574 if (prev !=
nullptr) prev->
setPNext(next);
577template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
581 for (
u_integer i = bucket + 1; i < buckets->size(); i++) {
585 return buckets->size();
588template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
592 if (bucket == 0)
return buckets->size();
593 for (
u_integer i = bucket - 1; i > 0; i--) {
600 return buckets->size();
603template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
606 : p_buckets(buckets), cur_bucket(bucket), p_node(node) {}
608template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
613template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
619 this->p_buckets = other.p_buckets;
620 this->p_node = other.p_node;
624template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
626 if (this->p_node && this->p_node->getPNext()) {
633template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
639 if (this->p_node->getPNext()) {
640 this->p_node = this->p_node->getPNext();
645 next_bucket != this->p_buckets->size()) {
646 this->cur_bucket = next_bucket;
647 this->p_node = this->p_buckets->get(next_bucket);
651 this->cur_bucket = this->p_buckets->size();
652 this->p_node =
nullptr;
655template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
661 for (
integer i = 0; i < steps; ++i) {
666template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
673 return this->p_node->getVal();
676template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
683 return this->p_node->getVal();
686template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
691template <
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
697 hashNode* old_node = old_buckets[i];
703 if (!prev_new_node) {
704 new_buckets[i] = new_node;
709 prev_new_node = new_node;
716template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
719 auto node = this->rebind_alloc.allocate(1);
720 this->rebind_alloc.construct(node, key, value, next);
724template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
726 this->rebind_alloc.destroy(node);
727 this->rebind_alloc.deallocate(node, 1);
730template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
736template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
739 return this->buckets.size();
742template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
746 return this->buckets[code];
749template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
755template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
765template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
776template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
783 for (
hashNode*& old_head : this->buckets) {
789 auto code = this->hash_(cur->
getKey()) % new_bucket_count;
792 new_buckets[code] = cur;
796 this->buckets = std::move(new_buckets);
799template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
803 }
else if (this->
loadFactor() >= LOAD_FACTOR_MAX){
808template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
810 : size_(0), hash_(std::move(
hash)) {
814template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
817 if (this->size_ == 0)
820 for (
auto cur = this->
getBucket(key); cur; cur = cur->getPNext()){
821 if (cur->getKey() == key)
827template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
829 if (
auto cur = this->
find(key)){
830 cur->setValue(value);
836template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
844 if (cur->getKey() == key)
847 for (; cur->getPNext(); cur = cur->getPNext()){
848 if (cur->getKey() == key)
858template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
860 if (this->size_ == 0)
866 hashNode* cur = this->buckets[code];
870 if (cur->
getKey() == key) {
874 this->buckets[code] = cur->
getPNext();
887template<
typename K_TYPE,
typename V_TYPE,
typename ALLOC,
typename HASH>
889 for (
hashNode*& bucket: this->buckets) {
891 auto next = bucket->getPNext();
Memory allocation interface and implementations.
Container for two heterogeneous elements.
Definition couple.h:37
Forward declaration of hash class template.
Definition hash.h:80
Forward iterator for hashTable.
Definition hashTable.h:261
void next() const
Advances to the next element.
Definition hashTable.h:634
couple< const K_TYPE, V_TYPE > & get()
Gets current key-value pair (non-const)
Definition hashTable.h:668
Iterator & operator=(const Iterator &other)
Copy assignment operator.
Definition hashTable.h:615
static u_integer findPrevValidBucket(vector< hashNode *, rebind_alloc_pointer > *buckets, u_integer bucket)
Finds the previous non-empty bucket.
Definition hashTable.h:590
void operator+=(integer steps) const
Advances iterator by steps positions.
Definition hashTable.h:656
bool isValid() const
Checks if iterator points to valid element.
Definition hashTable.h:687
bool hasNext() const
Checks if more elements are available.
Definition hashTable.h:625
Iterator(vector< hashNode *, rebind_alloc_pointer > *buckets=nullptr, u_integer bucket=0, hashNode *node=nullptr)
Constructs an iterator pointing to specific position.
Definition hashTable.h:604
static u_integer findNextValidBucket(vector< hashNode *, rebind_alloc_pointer > *buckets, u_integer bucket)
Finds the next non-empty bucket.
Definition hashTable.h:579
Internal node type for hash table storage.
Definition hashTable.h:71
hashNode * getPNext() const override
Gets next node in chain.
Definition hashTable.h:563
couple< const K_TYPE, V_TYPE > & getVal() override
Gets key-value pair (non-const)
Definition hashTable.h:520
const V_TYPE & getValue() const
Gets the value (const)
Definition hashTable.h:536
hashNode * getPPrev() const override
Not supported (throws unSupportedMethodError)
Definition hashTable.h:557
void setPNext(hashNode *new_next)
Sets next node in chain.
Definition hashTable.h:568
const K_TYPE & getKey() const
Gets the key (const)
Definition hashTable.h:531
hashNode(const K_TYPE &key=K_TYPE{}, const V_TYPE &value=V_TYPE{}, hashNode *next=nullptr)
Constructs a new hash node.
Definition hashTable.h:500
void setValue(const V_TYPE &value)
Sets a new value.
Definition hashTable.h:551
static void connect(hashNode *prev, hashNode *next)
Connects two nodes in chain.
Definition hashTable.h:573
void setVal(couple< const K_TYPE, V_TYPE > data) override
Not supported (throws unSupportedMethodError)
Definition hashTable.h:546
hashNode & operator=(const hashNode &other)
Copy assignment operator.
Definition hashTable.h:510
hashNode * createNode(const K_TYPE &key=K_TYPE{}, const V_TYPE &value=V_TYPE{}, hashNode *next=nullptr) const
Creates a new hash node.
Definition hashTable.h:718
bool modify(const K_TYPE &key, const V_TYPE &value)
Modifies value for existing key.
Definition hashTable.h:828
typename ALLOC::template rebind_alloc< hashNode * > rebind_alloc_pointer
Rebound allocator type for pointer storage.
Definition hashTable.h:174
~hashTable()
Destroys hashTable.
Definition hashTable.h:888
u_integer getPrevSize() const
Gets previous appropriate bucket size for shrinking.
Definition hashTable.h:766
static constexpr floating LOAD_FACTOR_MAX
Maximum load factor before expanding.
Definition hashTable.h:190
vector< hashNode *, rebind_alloc_pointer > buckets_type
Type representing the hash table buckets container.
Definition hashTable.h:180
u_integer getHashCode(const K_TYPE &key) const
Computes hash code for a key.
Definition hashTable.h:732
static constexpr u_integer BUCKETS_SIZES_COUNT
Size of BUCKETS_SIZES BUCKETS_SIZES.
Definition hashTable.h:196
static constexpr floating LOAD_FACTOR_MIN
Minimum load factor before shrinking.
Definition hashTable.h:185
void rehash(u_integer new_bucket_count)
Rehashes table to new bucket count.
Definition hashTable.h:777
typename ALLOC::template rebind_alloc< hashNode > rebind_alloc_node
Rebound allocator type for node storage.
Definition hashTable.h:168
u_integer getNextSize() const
Gets next appropriate bucket size for expansion.
Definition hashTable.h:756
buckets_type bucketsCopy(const buckets_type &old_buckets) const
Creates a deep copy of the hash table's bucket array.
Definition hashTable.h:693
bool insert(const K_TYPE &key, const V_TYPE &value)
Inserts new key-value pair.
Definition hashTable.h:837
hashNode * find(const K_TYPE &key) const
Finds node for given key.
Definition hashTable.h:816
hashTable(HASH hash=HASH{})
Constructs empty hashTable.
Definition hashTable.h:809
hashNode * getBucket(const K_TYPE &key) const
Gets bucket head for a key.
Definition hashTable.h:744
void destroyNode(hashNode *node) noexcept
Destroys a hash node.
Definition hashTable.h:725
void adjust()
Adjusts table size based on load factor.
Definition hashTable.h:800
floating loadFactor() const
Calculates current load factor.
Definition hashTable.h:751
bool erase(const K_TYPE &key)
Removes key-value pair.
Definition hashTable.h:859
u_integer getBucketCount() const
Gets current number of buckets.
Definition hashTable.h:738
static constexpr u_integer BUCKETS_SIZES[]
Predefined bucket sizes for hash table resizing.
Definition hashTable.h:229
Exception for container index out-of-range errors.
Definition error.h:84
Abstract base class for unique element containers.
Definition set.h:44
Exception for unimplemented method calls.
Definition error.h:123
Dynamic array container with amortized constant time operations.
Definition vector.h:43
u_integer size() const override
Gets the size of the vector.
Definition vector.h:640
Base class for linked value containers with formatted output.
Definition wrapper.h:28
Generic pair container implementation.
Provides a generic hashing utility and a base interface for hashable types.
Main namespace for the project Original.
Definition algorithms.h:21
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:43
double floating
Double-precision floating-point type.
Definition config.h:51
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:35
Single-direction iterator base class.
Dynamic array container with automatic resizing.
Abstract polymorphic container with value encapsulation and navigation support.