This commit is contained in:
Asuro
2025-04-13 01:46:36 +02:00
parent adbe518c6e
commit d75e5627f9
4 changed files with 92 additions and 1 deletions

Binary file not shown.

Binary file not shown.

91
src/game/util/HashMap.h Normal file
View File

@@ -0,0 +1,91 @@
#include "bx/hash.h"
#include <cassert>
#include <cstdint>
template <typename T> struct HashMapInsertResult
{
T& Obj = nullptr;
bool ElementExists = false;
};
template <typename T> struct HashMapInsertResultConst
{
const T& Obj = nullptr;
bool ElementExists = false;
};
// BitSize 16 will make the HashTable ~200kb with 65k entries
template <typename T, uint32_t BitSize> struct HashMapCore
{
static constexpr uint32_t SlotCount = (1 << BitSize);
static constexpr uint32_t RequiredDataSize = SlotCount * sizeof(T);
T* Data = nullptr;
uint32_t HashTable[SlotCount]{0};
// External array that should be RequiredDataSize bytes big
void Init(T* data, uint64_t dataSize)
{
Data = data;
assert(data != nullptr);
assert(dataSize == RequiredDataSize);
}
bool Has(uint32_t hash) const
{
return HashTable[FindIdx(hash)] == hash;
}
HashMapInsertResult<T> Get(uint32_t hash)
{
uint16_t idx = FindIdx(hash);
return {Data[idx], HashTable[idx] == hash};
}
const T& Get(uint32_t hash) const
{
uint16_t idx = FindIdx(hash);
return {Data[idx], HashTable[idx] == hash};
}
bool Remove(uint32_t hash); // TODO: requires tombstones so later entries survive
private:
uint16_t FindIdx(uint32_t hash) const
{
uint32_t mask = SlotCount - 1;
uint32_t idx = hash & mask;
uint32_t tableEntry = HashTable[idx];
uint32_t stepCount = 0;
while (tableEntry != hash && tableEntry != 0 && stepCount < UINT16_MAX)
{
idx = (idx + 1) % SlotCount;
tableEntry = HashTable[idx];
++stepCount;
}
assert(stepCount < UINT16_MAX);
return idx;
}
};
namespace HashMapTests
{
struct AAA
{
int X = 3;
int Y = 42;
};
inline void Test()
{
HashMapCore<AAA, 16> testMap;
AAA* backingData = new AAA[testMap.RequiredDataSize]();
testMap.Init(backingData, testMap.RequiredDataSize);
AAA test{};
AAA test2{5, 6};
testMap.Get(bx::hash<bx::HashMurmur3>(test)).Obj = test;
testMap.Get(bx::hash<bx::HashMurmur3>(test2)).Obj = test2;
delete[] backingData;
}
} // namespace HashMapTests

Binary file not shown.