Skip to content

Instantly share code, notes, and snippets.

@1995eaton
Created August 12, 2014 22:35
Show Gist options
  • Save 1995eaton/58815a1da9f4ba4ceb57 to your computer and use it in GitHub Desktop.
Save 1995eaton/58815a1da9f4ba4ceb57 to your computer and use it in GitHub Desktop.
C++ Hash Table
#include <iostream>
#include <vector>
using std::vector;
using std::pair;
using std::string;
uint8_t pearsonDigits[] = {106, 15, 244, 74, 82, 236, 14, 57, 224, 61, 241, 204, 26, 54, 30, 12, 18, 214, 166, 87, 107, 253, 152, 111, 79, 7, 27, 70, 147, 56, 75, 170, 231, 230, 248, 92, 63, 157, 1, 239, 154, 185, 20, 249, 175, 177, 250, 84, 80, 127, 150, 234, 211, 139, 11, 125, 4, 229, 138, 117, 247, 155, 196, 101, 120, 173, 25, 93, 186, 180, 128, 72, 17, 76, 77, 198, 116, 8, 134, 151, 91, 86, 113, 254, 251, 33, 135, 67, 118, 215, 89, 183, 189, 213, 90, 94, 78, 5, 129, 55, 97, 233, 193, 45, 226, 232, 212, 217, 66, 37, 109, 227, 209, 143, 181, 100, 35, 162, 133, 69, 58, 81, 195, 223, 132, 19, 240, 252, 71, 9, 190, 73, 148, 200, 153, 203, 110, 21, 163, 62, 222, 46, 38, 164, 50, 207, 103, 51, 192, 60, 96, 119, 41, 122, 136, 28, 165, 124, 242, 176, 114, 208, 156, 65, 184, 140, 39, 121, 174, 228, 34, 243, 182, 216, 188, 99, 115, 210, 172, 145, 225, 29, 142, 105, 83, 10, 42, 206, 235, 199, 85, 219, 160, 88, 168, 238, 141, 194, 167, 16, 221, 112, 237, 159, 23, 0, 104, 218, 13, 179, 205, 178, 255, 22, 52, 126, 123, 245, 59, 130, 202, 2, 32, 48, 169, 47, 197, 40, 53, 161, 6, 43, 98, 137, 108, 44, 102, 95, 191, 144, 201, 246, 171, 49, 31, 68, 131, 3, 64, 149, 146, 36, 187, 24, 220, 158};
uint64_t pear16(string input) {
size_t len = input.size();
uint64_t result = 0;
for (int i = 0; i < 8; i++) {
uint8_t h = pearsonDigits[(input.at(0) + i) % 256];
for (int j = 1; j < len; j++) {
h = pearsonDigits[h ^ input.at(j)];
}
result += h;
}
return result;
}
template<class V>
class HashTable {
private:
size_t table_size = 1;
size_t current_cap = 0;
double threshold_ratio = 0.75;
double threshold = table_size * threshold_ratio;
vector< vector<pair<string, V>> > table;
public:
HashTable() {
table.resize(table_size);
}
bool resize() {
if (current_cap > threshold) {
table_size *= 2;
threshold = table_size * threshold_ratio;
const vector< vector<pair<string, V>> > next_table = table;
table.clear();
table.resize(table_size);
for (auto& bucket: next_table) {
for (auto& entry: bucket) {
set(entry.first, entry.second, 0);
}
}
return true;
}
return false;
}
V& get(string key, bool should_set = 0) {
uint64_t bucket = pear16(key) % table_size;
for (auto& it: table[bucket]) {
if (it.first.compare(key) == 0) {
return it.second;
}
}
if (should_set) {
set(key, V());
return get(key);
}
}
void set(string key, V value, bool should_resize = 1) {
uint64_t bucket = pear16(key) % table_size;
for (auto& it: table[bucket]) {
if (it.first == key) {
it.second = value;
return;
}
}
if (should_resize && resize()) {
current_cap += 1;
bucket = pear16(key) % table_size;
}
table[bucket].push_back(make_pair(key, value));
}
void remove(string key) {
uint64_t bucket = pear16(key) % table_size;
size_t index = 0;
for (auto& it: table[bucket]) {
if (it.first.compare(key) == 0) {
table.at(bucket).erase(table.at(bucket).begin() + index);
return;
}
index++;
}
}
V& operator[](string key) {
return get(key, 1);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment