mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
141 lines
2.2 KiB
C++
141 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include "DebugCommon.h"
|
|
#include "BeefySysLib/Util/BumpAllocator.h"
|
|
|
|
NS_BF_DBG_BEGIN
|
|
|
|
template <typename T>
|
|
class StrBloomMap
|
|
{
|
|
public:
|
|
static const int HashSize = 9973;
|
|
Beefy::BumpAllocator mAlloc;
|
|
|
|
struct Entry
|
|
{
|
|
T mValue;
|
|
Entry* mNext;
|
|
};
|
|
|
|
struct Iterator
|
|
{
|
|
public:
|
|
StrBloomMap* mMap;
|
|
Entry* mCurEntry;
|
|
int mCurBucket;
|
|
|
|
public:
|
|
Iterator(StrBloomMap* map)
|
|
{
|
|
mMap = map;
|
|
mCurBucket = 0;
|
|
mCurEntry = NULL;
|
|
}
|
|
|
|
Iterator& operator++()
|
|
{
|
|
if (mCurEntry != NULL)
|
|
{
|
|
mCurEntry = mCurEntry->mNext;
|
|
if (mCurEntry != NULL)
|
|
return *this;
|
|
mCurBucket++;
|
|
}
|
|
|
|
while (mCurBucket < HashSize)
|
|
{
|
|
mCurEntry = mMap->mHashHeads[mCurBucket];
|
|
if (mCurEntry != NULL)
|
|
return *this;
|
|
mCurBucket++;
|
|
}
|
|
|
|
return *this; // At end
|
|
}
|
|
|
|
bool operator!=(const Iterator& itr) const
|
|
{
|
|
return ((itr.mCurEntry != mCurEntry) || (itr.mCurBucket != mCurBucket));
|
|
}
|
|
|
|
Entry* operator*()
|
|
{
|
|
return mCurEntry;
|
|
}
|
|
};
|
|
|
|
public:
|
|
int GetHash(const char* str, const char* strEnd)
|
|
{
|
|
if (str == NULL)
|
|
return 0;
|
|
|
|
int curHash = 0;
|
|
const char* curHashPtr = str;
|
|
while ((*curHashPtr != 0) && (curHashPtr != strEnd))
|
|
{
|
|
char c = *curHashPtr;
|
|
//if (c != ' ')
|
|
curHash = ((curHash ^ *curHashPtr) << 5) - curHash;
|
|
curHashPtr++;
|
|
}
|
|
return curHash & 0x7FFFFFFF;
|
|
}
|
|
|
|
public:
|
|
Entry** mHashHeads;
|
|
|
|
public:
|
|
StrBloomMap()
|
|
{
|
|
mHashHeads = NULL;
|
|
}
|
|
|
|
void InsertUnique(int hash, T value)
|
|
{
|
|
if (mHashHeads == NULL)
|
|
mHashHeads = (Entry**)mAlloc.AllocBytes(sizeof(Entry*) * HashSize, alignof(Entry*));
|
|
|
|
int hashIdx = hash % HashSize;
|
|
Entry* headEntry = mHashHeads[hashIdx];
|
|
|
|
Entry* checkEntry = headEntry;
|
|
while (checkEntry != NULL)
|
|
{
|
|
if (checkEntry->mValue == value)
|
|
return;
|
|
checkEntry = checkEntry->mNext;
|
|
}
|
|
|
|
Entry* newEntry = mAlloc.Alloc<Entry>();
|
|
newEntry->mValue = value;
|
|
newEntry->mNext = headEntry;
|
|
|
|
mHashHeads[hashIdx] = newEntry;
|
|
}
|
|
|
|
Entry* FindFirst(const char* name)
|
|
{
|
|
if (mHashHeads == NULL)
|
|
return NULL;
|
|
|
|
int hash = GetHash(name, NULL) % HashSize;
|
|
return mHashHeads[hash];
|
|
}
|
|
|
|
Iterator begin()
|
|
{
|
|
return ++Iterator(this);
|
|
}
|
|
|
|
Iterator end()
|
|
{
|
|
Iterator itr(this);
|
|
itr.mCurBucket = HashSize;
|
|
return itr;
|
|
}
|
|
};
|
|
|
|
NS_BF_DBG_END
|
|
|