#pragma once #include "DebugCommon.h" #include "BeefySysLib/Util/BumpAllocator.h" NS_BF_DBG_BEGIN template 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(); 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