summaryrefslogtreecommitdiff
path: root/include/fud_hash_map.hpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2025-04-02 06:43:43 -0500
committerDominick Allen <djallen@librehumanitas.org>2025-04-02 06:43:43 -0500
commite6d9330a978373ffc24209b5edf03eda6491f818 (patch)
tree9f24009ef6645263d9eb92bb338c69bd23d9afd5 /include/fud_hash_map.hpp
parent1d2ad781398d2a8743899eb54153998ca03ac090 (diff)
Add more testing for hash maps.
Diffstat (limited to 'include/fud_hash_map.hpp')
-rw-r--r--include/fud_hash_map.hpp113
1 files changed, 103 insertions, 10 deletions
diff --git a/include/fud_hash_map.hpp b/include/fud_hash_map.hpp
index dd6d080..9220876 100644
--- a/include/fud_hash_map.hpp
+++ b/include/fud_hash_map.hpp
@@ -194,10 +194,49 @@ class HashMap {
return FudStatus::Success;
}
- FudStatus replace(const Key& key, const Value& value);
- FudStatus replace(const Key& key, Value&& value);
- FudStatus replace(Key&& key, const Value& value);
- FudStatus replace(Key&& key, Value&& value);
+ FudStatus update(const Key& key, const Value& value)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return insert(key, value);
+ }
+ auto hashIndex{hashIndexOption.take()};
+ m_data[hashIndex].value() = value;
+ return FudStatus::Success;
+ }
+
+ FudStatus update(const Key& key, Value&& value)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return insert(key, std::move(value));
+ }
+ auto hashIndex{hashIndexOption.take()};
+ m_data[hashIndex].value() = std::move(value);
+ return FudStatus::Success;
+ }
+
+ FudStatus update(Key&& key, const Value& value)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return insert(std::move(key), value);
+ }
+ auto hashIndex{hashIndexOption.take()};
+ m_data[hashIndex].value() = value;
+ return FudStatus::Success;
+ }
+
+ FudStatus update(Key&& key, Value&& value)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return insert(std::move(key), std::move(value));
+ }
+ auto hashIndex{hashIndexOption.take()};
+ m_data[hashIndex].value() = std::move(value);
+ return FudStatus::Success;
+ }
FudStatus remove(const Key& key)
{
@@ -223,10 +262,61 @@ class HashMap {
return FudStatus::Success;
}
- Option<Value> extract(const Key& key);
- Option<Value> extract(Key& key);
- Node extractPair(const Key& key);
- Node extractPair(Key& key);
+ Option<Value> extract(const Key& key)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return NullOpt;
+ }
+
+ auto hashIndex{hashIndexOption.value()};
+ Option<Value> value{std::move(m_data[hashIndex].takeValue())};
+ m_data[hashIndex].tombstone();
+
+ return value;
+ }
+
+ Option<Value> extract(Key&& key)
+ {
+ auto hashIndexOption = lookup(std::move(key));
+ if (hashIndexOption.isNone()) {
+ return NullOpt;
+ }
+
+ auto hashIndex{hashIndexOption.value()};
+ Option<Value> value{std::move(m_data[hashIndex].takeValue())};
+ m_data[hashIndex].tombstone();
+
+ return value;
+ }
+
+ KeyValuePair extractPair(const Key& key)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return NullOpt;
+ }
+
+ auto hashIndex{hashIndexOption.value()};
+ KeyValuePair kvPair{key, m_data[hashIndex].takeValue()};
+ m_data[hashIndex].tombstone();
+
+ return kvPair;
+ }
+
+ KeyValuePair extractPair(Key&& key)
+ {
+ auto hashIndexOption = lookup(key);
+ if (hashIndexOption.isNone()) {
+ return NullOpt;
+ }
+
+ auto hashIndex{hashIndexOption.value()};
+ KeyValuePair kvPair{std::move(key), m_data[hashIndex].takeValue()};
+ m_data[hashIndex].tombstone();
+
+ return kvPair;
+ }
Option<Value> get(const Key& key)
{
@@ -328,7 +418,7 @@ class HashMap {
return status;
}
- Result<Value, FudStatus> exchange(const Key& key, const Value& value);
+ Result<Option<Value>, FudStatus> exchange(const Key& key, const Value& value);
protected:
[[nodiscard]] double loadFactor() const
@@ -398,6 +488,9 @@ class HashMap {
Option<size_t> lookup(const Key& key) const
{
+ if (m_count == 0 || m_buckets == 0 || m_data == nullptr) {
+ return NullOpt;
+ }
const auto hash = m_hasher(key, m_seed);
const auto nearestPowerOf2 = detail::roundToNearest2(m_buckets);
size_t probe = 0;
@@ -419,7 +512,7 @@ class HashMap {
}
}
- if (collision and m_data[hashIndex].key() == key) {
+ if (collision and hashIndex < m_buckets and m_data[hashIndex].key() == key) {
return hashIndex;
}