Changed hashmaps to not use pointers, saving on allocations

This commit is contained in:
2026-03-02 16:57:52 +02:00
parent c388f20429
commit 084eb8266b

View File

@@ -30,18 +30,16 @@ public:
keyHashPosition = keyHash % storage.size(); keyHashPosition = keyHash % storage.size();
// Empty bucket // Empty bucket
if (storage[keyHashPosition] == nullptr) { if (!storage[keyHashPosition].empty()) {
storage[keyHashPosition] = new std::vector<hashStorage>;
} else {
// Throws // Throws
Systems::Logging::Log("Trying to inserting same key twice! Throwing...", Systems::Logging::Log("Trying to inserting same key twice! Throwing...",
"Hashmap", Systems::Logging::LogLevel::Error, "Hashmap", Systems::Logging::LogLevel::Error,
Has(key)); Has(key));
} }
storage[keyHashPosition]->emplace_back(key, std::move(value), keyHash); storage[keyHashPosition].emplace_back(key, std::move(value), keyHash);
currentLoadFactor = (++count) / static_cast<float>(bucketCount); currentLoadFactor = (++count) / static_cast<float>(bucketCount);
return storage[keyHashPosition]->back().value; return storage[keyHashPosition].back().value;
} }
void Remove(const Key &key) { void Remove(const Key &key) {
@@ -51,8 +49,8 @@ public:
// Throws // Throws
Systems::Logging::Log("Trying to remove a non-existant key! Throwing...", Systems::Logging::Log("Trying to remove a non-existant key! Throwing...",
"Hashmap", Systems::Logging::LogLevel::Error, "Hashmap", Systems::Logging::LogLevel::Error,
storage[keyHashPosition] == nullptr); storage[keyHashPosition].empty());
std::erase_if(*storage[keyHashPosition], std::erase_if(storage[keyHashPosition],
[keyHash, &key](const hashStorage &hash) { [keyHash, &key](const hashStorage &hash) {
return hash.hash == keyHash && hash.key == key; return hash.hash == keyHash && hash.key == key;
}); });
@@ -69,11 +67,11 @@ public:
keyHashPosition = keyHash % storage.size(); keyHashPosition = keyHash % storage.size();
// Empty bucket // Empty bucket
if (storage[keyHashPosition] == nullptr) { if (storage[keyHashPosition].empty()) {
return false; return false;
} }
for (const hashStorage &hash : *storage[keyHashPosition]) { for (const hashStorage &hash : storage[keyHashPosition]) {
if (hash.hash == keyHash && hash.key == key) { if (hash.hash == keyHash && hash.key == key) {
return true; return true;
} }
@@ -90,9 +88,9 @@ public:
Systems::Logging::Log( Systems::Logging::Log(
"Trying to access a non-existant bucket for a key! Throwing...", "Trying to access a non-existant bucket for a key! Throwing...",
"Hashmap", Systems::Logging::LogLevel::Error, "Hashmap", Systems::Logging::LogLevel::Error,
storage[keyHashPosition] == nullptr); storage[keyHashPosition].empty());
for (hashStorage &hash : *storage[keyHashPosition]) { for (hashStorage &hash : storage[keyHashPosition]) {
if (hash.hash == keyHash && hash.key == key) { if (hash.hash == keyHash && hash.key == key) {
return hash.value; return hash.value;
} }
@@ -103,14 +101,7 @@ public:
} }
void Clear() noexcept { void Clear() noexcept {
for (bucket *entry : storage) { storage.clear();
if (entry == nullptr) {
continue;
}
entry->clear();
delete entry;
}
count = 0; count = 0;
} }
@@ -142,22 +133,17 @@ private:
} }
currentlyRehashing = true; currentlyRehashing = true;
std::vector<bucket *> oldStorage = std::move(storage); std::vector<bucket> oldStorage = std::move(storage);
storage = std::vector<bucket *>(); storage = std::vector<bucket>();
storage.resize(goalBucketCount); storage.resize(goalBucketCount);
// Repopulate and cleanup // Repopulate and cleanup
for (bucket *entry : oldStorage) { for (bucket &entry : oldStorage) {
if (entry == nullptr) { for (const hashStorage &hash : entry) {
continue;
}
for (const hashStorage &hash : *entry) {
Insert(hash.key, hash.value); Insert(hash.key, hash.value);
} }
entry->clear(); entry.clear();
delete entry;
} }
// It's necessary to write these again due to insert above // It's necessary to write these again due to insert above
@@ -175,7 +161,7 @@ private:
}; };
using bucket = std::vector<hashStorage>; using bucket = std::vector<hashStorage>;
std::vector<bucket *> storage; std::vector<bucket> storage;
std::size_t count = 0, bucketCount = minimumBucketCount; std::size_t count = 0, bucketCount = minimumBucketCount;
float currentLoadFactor = 0; float currentLoadFactor = 0;
bool currentlyRehashing = false; // Lock for Insert in rehash bool currentlyRehashing = false; // Lock for Insert in rehash