Changed hashmaps to not use pointers, saving on allocations
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user