stuff
This commit is contained in:
Binary file not shown.
Binary file not shown.
91
src/game/util/HashMap.h
Normal file
91
src/game/util/HashMap.h
Normal 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
|
||||||
BIN
tools/minidef.exe
LFS
BIN
tools/minidef.exe
LFS
Binary file not shown.
Reference in New Issue
Block a user