-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopen_address_hash.h
81 lines (65 loc) · 1.98 KB
/
open_address_hash.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright Ben Roberts 2024
#pragma once
#include "vector.h" // For Vector
#include <functional> // For std::hash
#include <stdexcept> // For std::exception
template <typename KeyType, typename ValueType> class OpenAddressHash {
private:
struct Entry {
KeyType key;
ValueType value;
bool empty = true;
};
Vector<Entry> table_;
size_t num_elements_;
float load_factor_;
size_t capacity() const { return table_.capacity(); }
size_t standardHash(const KeyType &key) const {
return std::hash<KeyType>{}(key) % capacity();
}
void rehash(size_t newCapacity) {
auto old_table = table_;
table_ = Vector<Entry>(newCapacity);
num_elements_ = 0;
for (const auto &entry : old_table) {
if (!entry.empty) {
insert(entry.key, entry.value);
}
}
}
public:
explicit OpenAddressHash(size_t capacity = 8, float load_factor = 0.5)
: table_(capacity), num_elements_(0), load_factor_(load_factor) {}
void insert(const KeyType &key, const ValueType &value) {
if (static_cast<float>(num_elements_ + 1) / capacity() > load_factor_) {
rehash(capacity() * 2);
}
size_t index = standardHash(key);
size_t probe = index;
while (!table_[probe].empty) {
if (table_[probe].key == key) {
// Update existing key
table_[probe].value = value;
return;
}
probe = (probe + 1) % capacity();
}
table_[probe] = {key, value, false};
num_elements_++;
}
ValueType get(const KeyType &key) {
size_t index = standardHash(key);
size_t probe = index;
while (!table_[probe].empty) {
if (table_[probe].key == key) {
return table_[probe].value;
}
probe = (probe + 1) % capacity();
if (probe == index) {
break; // Searched the entire table
}
}
assert(false && "Key does not exist in the table!");
}
size_t size() const { return num_elements_; }
};