-
Notifications
You must be signed in to change notification settings - Fork 76
/
Copy pathhash.hpp
73 lines (62 loc) · 2.07 KB
/
hash.hpp
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
#ifndef __hash__
#define __hash__
#include <cassert>
#include <iostream>
#include <limits>
#include <vector>
#include "../part-1/list.hpp"
template <typename K, typename V, typename H> class HashTable
{
public:
HashTable(size_t num_chains) : _table{num_chains} {}
void insert(const K &key, const V &value)
{
size_t slot = _get_slot(key);
Node<KeyValuePair> *node = _find_key(slot, key);
if (!node) {
list_insert_after(&_table[slot], {key, value});
} else {
node->next->value.value = value;
}
}
V *get(const K &key)
{
size_t slot = _get_slot(key);
Node<KeyValuePair> *node = _find_key(slot, key);
if (!node) { return nullptr; }
return &node->next->value.value;
}
void print(bool details = false) const
{
size_t min = std::numeric_limits<size_t>::max(), max = 0, average = 0;
for (size_t slot = 0; slot < _table.size(); ++slot) {
if (details) { std::cout << "Slot " << slot << " contains"; }
size_t count = 0;
for (Node<KeyValuePair> *node = _table[slot].next.get(); node;
node = node->next.get()) {
if (details) { std::cout << " '" << node->value.key << '\''; }
count++;
}
if (details) { std::cout << " (" << count << ")\n"; }
max = std::max(count, max);
min = std::min(count, min);
average += count;
}
std::cout << "Slot sizes: min: " << min;
std::cout << ", max: " << max;
std::cout << ", average: " << float(average) / _table.size() << '\n';
}
private:
struct KeyValuePair {
K key;
V value;
};
std::vector<Node<KeyValuePair>> _table;
size_t _get_slot(const K &key) const { return H{}(key) % _table.size(); }
Node<KeyValuePair> *_find_key(size_t slot, const K &key)
{
auto match = [&](const KeyValuePair &pair) { return pair.key == key; };
return list_find_predecessor(&_table[slot], match);
}
};
#endif // __hash__