From cd60c4abaf8955400fb93ed417ab10b545d046e0 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 10 May 2024 22:10:34 -0500 Subject: [PATCH] [ox/std] Fix bugs in HashMap and SmallMap --- deps/ox/src/ox/std/hashmap.hpp | 17 +++++----- deps/ox/src/ox/std/smallmap.hpp | 57 +++++++++++++-------------------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/deps/ox/src/ox/std/hashmap.hpp b/deps/ox/src/ox/std/hashmap.hpp index 2475359d..d38e2c8f 100644 --- a/deps/ox/src/ox/std/hashmap.hpp +++ b/deps/ox/src/ox/std/hashmap.hpp @@ -133,17 +133,18 @@ constexpr HashMap &HashMap::operator=(HashMap &&other) noexcep template constexpr T &HashMap::operator[](MaybeView_t const&k) { - auto &p = access(m_pairs, k); - if (p == nullptr) { + auto p = &access(m_pairs, k); + if (*p == nullptr) { if (static_cast(m_pairs.size()) * 0.7 < static_cast(m_keys.size())) { expand(); + p = &access(m_pairs, k); } - p = new Pair; - p->key = k; + *p = new Pair; + (*p)->key = k; m_keys.emplace_back(k); } - return p->value; + return (*p)->value; } template @@ -208,7 +209,7 @@ constexpr void HashMap::clear() { template constexpr void HashMap::expand() { - Vector r; + Vector r(m_pairs.size() * 2); for (std::size_t i = 0; i < m_keys.size(); ++i) { auto const&k = m_keys[i]; access(r, k) = std::move(access(m_pairs, k)); @@ -221,7 +222,7 @@ template constexpr typename HashMap::Pair *const&HashMap::access(Vector const&pairs, KK const&k) const { auto h = static_cast(ox::hash{}(k) % pairs.size()); while (true) { - const auto &p = pairs[h]; + auto const&p = *pairs.at(h).unwrap(); if (p == nullptr || p->key == k) { return p; } else { @@ -235,7 +236,7 @@ template constexpr typename HashMap::Pair *&HashMap::access(Vector &pairs, KK const&k) { auto h = static_cast(ox::hash{}(k) % pairs.size()); while (true) { - auto &p = pairs[h]; + auto &p = *pairs.at(h).unwrap(); if (p == nullptr || p->key == k) { return p; } else { diff --git a/deps/ox/src/ox/std/smallmap.hpp b/deps/ox/src/ox/std/smallmap.hpp index 76ad9370..db2fa3eb 100644 --- a/deps/ox/src/ox/std/smallmap.hpp +++ b/deps/ox/src/ox/std/smallmap.hpp @@ -67,13 +67,11 @@ class SmallMap { constexpr void clear(); private: - constexpr void expand(); + template + constexpr Pair const&access(Vector const&pairs, KK const&key, bool &isNew) const; template - constexpr Pair *const&access(Vector const&pairs, KK const&key) const; - - template - constexpr Pair *&access(Vector &pairs, KK const&key); + constexpr Pair &access(Vector &pairs, KK const&key, bool &isNew); }; @@ -133,15 +131,10 @@ constexpr SmallMap &SmallMap::operator=(SmallMap &&other) noex template constexpr T &SmallMap::operator[](MaybeView_t const&k) { - auto &p = access(m_pairs, k); - if (p == nullptr) { - if (static_cast(m_pairs.size()) * 0.7 < - static_cast(m_keys.size())) { - expand(); - } - p = new Pair; + bool isNew{}; + auto p = &access(m_pairs, k, isNew); + if (isNew) { p->key = k; - m_keys.emplace_back(k); } return p->value; } @@ -194,45 +187,41 @@ constexpr Vector const&SmallMap::keys() const noexcept { template constexpr void SmallMap::clear() { - for (std::size_t i = 0; i < m_pairs.size(); i++) { - delete m_pairs[i]; - } m_pairs.clear(); m_pairs.resize(127); } -template -constexpr void SmallMap::expand() { - Vector r; - for (std::size_t i = 0; i < m_keys.size(); ++i) { - auto const&k = m_keys[i]; - access(r, k) = std::move(access(m_pairs, k)); - } - m_pairs = std::move(r); -} - template template -constexpr typename SmallMap::Pair *const&SmallMap::access( - Vector const&pairs, KK const&k) const { +constexpr typename SmallMap::Pair const&SmallMap::access( + Vector const&pairs, KK const&k, bool &isNew) const { for (auto const&p : pairs) { if (p.key == k) { - return &p; + isNew = false; + return p; } } - return nullptr; + isNew = true; + m_keys.emplace_back(K(k)); + return pairs.emplace_back(); } template template -constexpr typename SmallMap::Pair *&SmallMap::access( - Vector &pairs, KK const&k) { +constexpr typename SmallMap::Pair &SmallMap::access( + Vector &pairs, KK const&k, bool &isNew) { for (auto &p : pairs) { if (p.key == k) { - return &p; + isNew = false; + return p; } } - return nullptr; + isNew = true; + if (static_cast(m_pairs.size()) * 0.7 < + static_cast(m_keys.size())) { + } + m_keys.emplace_back(K(k)); + return pairs.emplace_back(); } }