diff --git a/deps/ox/src/ox/std/hashmap.hpp b/deps/ox/src/ox/std/hashmap.hpp index c7ced32e..336598aa 100644 --- a/deps/ox/src/ox/std/hashmap.hpp +++ b/deps/ox/src/ox/std/hashmap.hpp @@ -39,10 +39,17 @@ class HashMap { std::size_t size() const noexcept; private: + void expand() noexcept; + /** * K is assumed to be a null terminated string. */ - static std::uint64_t hash(K, int len = 0xFFFF); + static std::uint64_t hash(K, int len = 0xFFFF) noexcept; + + /** + * K is assumed to be a null terminated string. + */ + Pair *&access(Vector &pairs, K key) noexcept; }; @@ -72,30 +79,35 @@ HashMap &HashMap::operator=(HashMap &other) noexcept { template T &HashMap::operator[](K k) noexcept { - auto h = hash(k) % m_pairs.size(); - auto hashStr = reinterpret_cast(&h); - while (1) { - auto &p = m_pairs[h]; - if (p == nullptr) { - p = new Pair; - p->key = k; - m_keys.push_back(k); - return p->value; - } else if (ox_strcmp(p->key, k) == 0) { - return p->value; - } else { - h = hash(hashStr, 8) % m_pairs.size(); + auto &p = access(m_pairs, k); + if (p == nullptr) { + if (m_pairs.size() * 0.7 < m_keys.size()) { + expand(); } + p = new Pair; + p->key = k; + m_keys.push_back(k); } + return p->value; } template std::size_t HashMap::size() const noexcept { return m_keys.size(); -}; +} template -std::uint64_t HashMap::hash(K k, int len) { +void HashMap::expand() noexcept { + Vector r; + for (std::size_t i = 0; i < m_keys.size(); i++) { + auto k = m_keys[i]; + access(r, k) = access(m_pairs, k); + } + m_pairs = r; +} + +template +std::uint64_t HashMap::hash(K k, int len) noexcept { std::uint64_t sum = 1; for (int i = 0; i < len && k[i]; i++) { sum += ((sum + k[i]) * 7) * sum; @@ -103,4 +115,18 @@ std::uint64_t HashMap::hash(K k, int len) { return sum; } +template +typename HashMap::Pair *&HashMap::access(Vector &pairs, K k) noexcept { + auto h = hash(k) % pairs.size(); + auto hashStr = reinterpret_cast(&h); + while (1) { + auto &p = pairs[h]; + if (p == nullptr || ox_strcmp(p->key, k) == 0) { + return p; + } else { + h = hash(hashStr, 8) % pairs.size(); + } + } +} + } diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index cebc475e..1d5b8415 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -59,7 +59,6 @@ map> tests = { ox::HashMap v; v["asdf"] = 42; v["aoeu"] = 100; - std::cout << v["asdf"]; oxAssert(v["asdf"] == 42, "asdf != 42"); oxAssert(v["aoeu"] == 100, "aoeu != 100"); return 0;