12 #pragma warning(disable : 4100 4127 4189 4201 4245 4389 4505 4701 4706) 22 #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = NULL; } } 23 #define SAFE_ADDREF(p) { if (p) { (p)->AddRef(); } } 25 #define SAFE_DELETE_ARRAY(p) { delete [](p); p = NULL; } 26 #define SAFE_DELETE(p) { delete (p); p = NULL; } 29 #define __BREAK_ON_FAIL { __debugbreak(); } 31 #define __BREAK_ON_FAIL 34 #define VA(x, action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; return hr; } } 35 #define VNA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_OUTOFMEMORY; goto lExit; } } 36 #define VBA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_FAIL; goto lExit; } } 37 #define VHA(x,action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; goto lExit; } } 39 #define V(x) { VA (x, 0) } 40 #define VN(x) { VNA(x, 0) } 41 #define VB(x) { VBA(x, 0) } 42 #define VH(x) { VHA(x, 0) } 44 #define VBD(x,str) { VBA(x, DPF(1,str)) } 45 #define VHD(x,str) { VHA(x, DPF(1,str)) } 47 #define VEASSERT(x) { hr = (x); if (FAILED(hr)) { __BREAK_ON_FAIL; D3DXASSERT(!#x); goto lExit; } } 48 #define VNASSERT(x) { if (!(x)) { __BREAK_ON_FAIL; D3DXASSERT(!#x); hr = E_OUTOFMEMORY; goto lExit; } } 50 #define ANALYSIS_ASSUME(x) { D3DXASSERT(x); __analysis_assume(x); __assume(x); } 52 #define D3DX11FLTASSIGN(a,b) { *reinterpret_cast< UINT32* >(&(a)) = *reinterpret_cast< UINT32* >(&(b)); } 55 static const UINT c_DataAlignment =
sizeof(UINT_PTR);
59 D3DXASSERT((Alignment & (Alignment - 1)) == 0);
62 return (Value + Alignment - 1) & (~(Alignment - 1));
67 D3DXASSERT((Alignment & (Alignment - 1)) == 0);
69 return (
void *)(((UINT_PTR)pValue + Alignment - 1) & (~((UINT_PTR)Alignment - 1)));
74 D3DX11INLINE
void dwordMemcpy( __out_bcount(uByteCount)
void * __restrict pDest, __in_bcount(uByteCount) CONST
void * __restrict pSource, UINT uByteCount)
79 const UINT qwordCount = uByteCount >> 3;
81 __int64* src64 = (__int64*) pSource;
82 __int64* dst64 = (__int64*) pDest;
84 for (i=0; i<(qwordCount & 0x3); i++)
91 for (; i<qwordCount; i+= 4)
93 *(dst64 ) = *(src64 );
94 *(dst64 + 1 ) = *(src64 + 1 );
95 *(dst64 + 2 ) = *(src64 + 2 );
96 *(dst64 + 3 ) = *(src64 + 3 );
101 ANALYSIS_ASSUME( dst64 - static_cast< __int64* >(pDest) <= uByteCount - 4 );
102 ANALYSIS_ASSUME( src64 - static_cast< const __int64* >(pSource) <= uByteCount - 4 );
103 if( uByteCount & 0x4 )
105 *((UINT*)dst64) = *((UINT*)src64);
108 const UINT dwordCount = uByteCount >> 2;
110 for (i=0; i<(dwordCount & 0x3); i++)
112 #pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION, "(dwordCount & 03) < dwordCount") 113 ((UINT*)pDest)[i ] = ((UINT*)pSource)[i ];
115 for (; i<dwordCount; i+= 4)
117 ((UINT*)pDest)[i ] = ((UINT*)pSource)[i ];
118 ((UINT*)pDest)[i+1] = ((UINT*)pSource)[i+1];
119 ((UINT*)pDest)[i+2] = ((UINT*)pSource)[i+2];
120 ((UINT*)pDest)[i+3] = ((UINT*)pSource)[i+3];
139 HRESULT SetData(
const void *
pData, SIZE_T size);
141 HRESULT Read(UINT *pUint);
142 HRESULT Read(
void **ppData, SIZE_T size);
143 HRESULT Read(LPCSTR *ppString);
145 HRESULT ReadAtOffset(SIZE_T offset, SIZE_T size,
void **ppData);
146 HRESULT ReadAtOffset(SIZE_T offset, LPCSTR *ppString);
148 SIZE_T GetPosition();
149 HRESULT Seek(SIZE_T offset);
166 _declspec(selectany)
unsigned int g_TimerRolloverCount = 0x80000000;
189 return Reserve(m_CurSize + 1);
194 if (DesiredSize > m_MaxSize)
197 UINT newSize = max(m_MaxSize * 2, DesiredSize);
202 if ((newSize < m_MaxSize) || (newSize < m_CurSize) || (newSize >= UINT_MAX /
sizeof(T)))
204 m_hLastError = E_OUTOFMEMORY;
208 pNewData =
NEW BYTE[newSize *
sizeof(T)];
209 if (pNewData == NULL)
211 m_hLastError = E_OUTOFMEMORY;
217 memcpy(pNewData, m_pData, m_CurSize *
sizeof(T));
225 m_pCastData = (T*) m_pData;
240 m_CurSize = m_MaxSize = 0;
252 BYTE tempData[
sizeof(*this)];
254 memcpy(tempData,
this,
sizeof(*
this));
255 memcpy(
this, &vOther,
sizeof(*
this));
256 memcpy(&vOther, tempData,
sizeof(*
this));
270 for (i = 0; i < m_CurSize; ++ i)
272 ((T*)m_pData)[i] = ((T*)vOther.
m_pData)[i];
278 m_pCastData = (T*) m_pData;
311 for (i = 0; i < m_CurSize; ++ i)
313 ((T*)m_pData + i)->~T();
325 return new((T*)m_pData + (m_CurSize ++)) T;
330 if (m_CurSize + count < m_CurSize)
332 m_hLastError = E_OUTOFMEMORY;
336 if (FAILED(Reserve(m_CurSize + count)))
339 T *
pData = (T*)m_pData + m_CurSize;
341 for (i = 0; i < count; ++ i)
354 memcpy((T*)m_pData + m_CurSize, &var,
sizeof(T));
362 if (m_CurSize + count < m_CurSize)
364 m_hLastError = E_OUTOFMEMORY;
368 if (FAILED(Reserve(m_CurSize + count)))
371 memcpy((T*)m_pData + m_CurSize, pVar, count *
sizeof(T));
384 memmove((T*)m_pData + index + 1, (T*)m_pData + index, (m_CurSize - index) *
sizeof(T));
385 memcpy((T*)m_pData + index, &var,
sizeof(T));
395 if (m_CurSize + count < m_CurSize)
397 m_hLastError = E_OUTOFMEMORY;
401 if (FAILED(Reserve(m_CurSize + count)))
404 memmove((T*)m_pData + index + count, (T*)m_pData + index, (m_CurSize - index) *
sizeof(T));
405 memcpy((T*)m_pData + index, pVar, count *
sizeof(T));
414 return ((T*)m_pData)[index];
423 memmove((T*)m_pData + index, (T*)m_pData + index + 1, (m_CurSize - index) *
sizeof(T));
432 memcpy((T*)m_pData + index, (T*)m_pData + m_CurSize,
sizeof(T));
449 for (i = 0; i < m_CurSize; ++ i)
451 if (((T*)m_pData + i) == pEntry)
458 void Sort(
int (__cdecl *pfnCompare)(
const void *pElem1,
const void *pElem2))
460 qsort(m_pData, m_CurSize,
sizeof(T), pfnCompare);
475 for (i=0; i<m_CurSize; i++)
493 for (i = 0; i < m_CurSize; ++ i)
536 m_bValid = value.m_bValid;
537 m_Value = value.m_Value;
554 m_Value += other.m_Value;
556 if (m_Value < other.m_Value)
577 if (other.m_Value != 0)
579 if (m_Value > MaxValue / other.m_Value)
584 m_Value *= other.m_Value;
623 HRESULT AddData(
const void *pNewData, UINT bufferSize,
CDataBlock **ppBlock);
626 void* Allocate(UINT bufferSize,
CDataBlock **ppBlock);
628 void EnableAlignment();
652 HRESULT AddString(LPCSTR pString, UINT *pOffset);
653 HRESULT AddData(
const void *pNewData, UINT bufferSize, UINT *pOffset);
655 void* Allocate(UINT buffferSize);
657 void EnableAlignment();
667 static void* __cdecl
operator new(
size_t s,
CDataBlockStore &pAllocator)
670 return pAllocator.Allocate( (UINT)s );
673 static void __cdecl
operator delete(
void* p,
CDataBlockStore &pAllocator)
682 #define HASH_MIX(a,b,c) \ 684 a -= b; a -= c; a ^= (c>>13); \ 685 b -= c; b -= a; b ^= (a<<8); \ 686 c -= a; c -= b; c ^= (b>>13); \ 687 a -= b; a -= c; a ^= (c>>12); \ 688 b -= c; b -= a; b ^= (a<<16); \ 689 c -= a; c -= b; c ^= (b>>5); \ 690 a -= b; a -= c; a ^= (c>>3); \ 691 b -= c; b -= a; b ^= (a<<10); \ 692 c -= a; c -= b; c ^= (b>>15); \ 695 static UINT ComputeHash(BYTE *pb, UINT cbToHash)
709 UINT *pdw =
reinterpret_cast<UINT *
>(pb);
724 case 11: c+=((UINT) pb[10] << 24);
725 case 10: c+=((UINT) pb[9] << 16);
726 case 9 : c+=((UINT) pb[8] << 8);
728 case 8 : b+=((UINT) pb[7] << 24);
729 case 7 : b+=((UINT) pb[6] << 16);
730 case 6 : b+=((UINT) pb[5] << 8);
732 case 4 : a+=((UINT) pb[3] << 24);
733 case 3 : a+=((UINT) pb[2] << 16);
734 case 2 : a+=((UINT) pb[1] << 8);
743 static UINT ComputeHashLower(BYTE *pb, UINT cbToHash)
758 for( UINT i = 0; i < 12; i++ )
759 pbT[i] = (BYTE)tolower(pb[i]);
761 UINT *pdw =
reinterpret_cast<UINT *
>(pbT);
775 for( UINT i = 0; i < cbLeft; i++ )
776 pbT[i] = (BYTE)tolower(pb[i]);
780 case 11: c+=((UINT) pbT[10] << 24);
781 case 10: c+=((UINT) pbT[9] << 16);
782 case 9 : c+=((UINT) pbT[8] << 8);
784 case 8 : b+=((UINT) pbT[7] << 24);
785 case 7 : b+=((UINT) pbT[6] << 16);
786 case 6 : b+=((UINT) pbT[5] << 8);
788 case 4 : a+=((UINT) pbT[3] << 24);
789 case 3 : a+=((UINT) pbT[2] << 16);
790 case 2 : a+=((UINT) pbT[1] << 8);
800 static UINT ComputeHash(LPCSTR pString)
802 return ComputeHash((BYTE*) pString, (UINT)strlen(pString));
811 static const UINT c_PrimeSizes[] =
843 static const UINT c_NumPrimes =
sizeof(c_PrimeSizes) /
sizeof(UINT);
845 template<
typename T, BOOL (*pfnIsEqual)(const T &Data1, const T &Data2)>
876 return pHashEntry->
Data;
882 return pHashEntry->
Hash;
888 m_rgpHashEntries = NULL;
891 m_bOwnHashEntryArray =
false;
900 UINT valuesMigrated = 0;
908 ZeroMemory(rgpNewHashEntries,
sizeof(
SHashEntry*) * actualSize);
913 while (!pOther->
PastEnd(&iter))
915 UINT index = iter.
GetHash() % actualSize;
927 pNewEntry->
pNext = rgpNewHashEntries[index];
930 rgpNewHashEntries[index] = pNewEntry;
938 m_rgpHashEntries = rgpNewHashEntries;
939 m_NumHashSlots = actualSize;
941 m_bOwnHashEntryArray =
true;
942 rgpNewHashEntries = NULL;
952 if (m_bOwnHashEntryArray)
955 m_bOwnHashEntryArray =
false;
965 SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
967 while (NULL != pCurrentEntry)
969 pTempEntry = pCurrentEntry->
pNext;
971 pCurrentEntry = pTempEntry;
988 for (UINT i = 0; i < c_NumPrimes; ++ i)
990 if (c_PrimeSizes[i] >= DesiredSize)
992 return c_PrimeSizes[i];
1002 HRESULT
Grow(__in UINT DesiredSize,
1003 __in UINT ProvidedArraySize = 0,
1004 __in_ecount_opt(ProvidedArraySize)
1005 void** ProvidedArray = NULL,
1006 __in
bool OwnProvidedArray =
false)
1011 UINT valuesMigrated = 0;
1014 VB( DesiredSize > m_NumHashSlots );
1018 if (ProvidedArray &&
1019 ProvidedArraySize >= actualSize)
1021 rgpNewHashEntries =
reinterpret_cast<SHashEntry**
>(ProvidedArray);
1025 OwnProvidedArray =
true;
1030 ZeroMemory(rgpNewHashEntries,
sizeof(
SHashEntry*) * actualSize);
1037 UINT index = iter.
GetHash() % actualSize;
1056 m_rgpHashEntries = rgpNewHashEntries;
1057 m_NumHashSlots = actualSize;
1058 m_bOwnHashEntryArray = OwnProvidedArray;
1067 if (m_NumEntries >= m_NumHashSlots)
1070 return Grow(m_NumEntries * 2 + 1);
1076 void PrintHashTableStats()
1078 if (m_NumHashSlots == 0)
1080 DPF(0,
"Uninitialized hash table!");
1085 float variance = 0.0f;
1087 UINT unusedSlots = 0;
1089 DPF(0,
"Hash table slots: %d, Entries in table: %d", m_NumHashSlots, m_NumEntries);
1094 SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
1096 while (NULL != pCurrentEntry)
1098 SHashEntry *pCurrentEntry2 = m_rgpHashEntries[i];
1101 while (pCurrentEntry2 != pCurrentEntry)
1103 if (pCurrentEntry->
Hash == pCurrentEntry2->
Hash)
1105 if (pfnIsEqual(pCurrentEntry->
Data, pCurrentEntry2->
Data))
1108 DPF(0,
"Duplicate entry (identical hash, identical data) found!");
1112 DPF(0,
"Hash collision (hash: %d)", pCurrentEntry->
Hash);
1115 pCurrentEntry2 = pCurrentEntry2->
pNext;
1118 pCurrentEntry = pCurrentEntry->
pNext;
1128 variance += (float)entries * (
float)entries / mean;
1131 variance /= max(1.0f, (m_NumHashSlots - 1));
1132 variance -= (mean * mean);
1134 DPF(0,
"Mean number of entries per slot: %f, Standard deviation: %f, Unused slots; %d", mean, variance, unusedSlots);
1144 SHashEntry *pEntry = m_rgpHashEntries[index];
1145 while (NULL != pEntry)
1147 if (Hash == pEntry->
Hash && pfnIsEqual(pEntry->
Data, Data))
1149 pIterator->
ppHashSlot = m_rgpHashEntries + index;
1153 pEntry = pEntry->
pNext;
1164 SHashEntry *pEntry = m_rgpHashEntries[index];
1165 while (NULL != pEntry)
1167 if (Hash == pEntry->
Hash)
1169 pIterator->
ppHashSlot = m_rgpHashEntries + index;
1173 pEntry = pEntry->
pNext;
1189 pHashEntry->
pNext = m_rgpHashEntries[index];
1190 pHashEntry->
Data = Data;
1191 pHashEntry->
Hash = Hash;
1192 m_rgpHashEntries[index] = pHashEntry;
1265 *ppPrev = pTemp->
pNext;
1270 ppPrev = &pTemp->
pNext;
1271 pTemp = pTemp->
pNext;
1284 template<
typename T, BOOL (*pfnIsEqual)(const T &Data1, const T &Data2)>
1293 m_pPrivateHeap = NULL;
1312 m_pPrivateHeap = pPrivateHeap;
1324 UINT index = Hash % m_NumHashSlots;
1327 pHashEntry->
pNext = m_rgpHashEntries[index];
1328 pHashEntry->
Data = Data;
1329 pHashEntry->
Hash = Hash;
1330 m_rgpHashEntries[index] = pHashEntry;
static UINT GetNextHashTableSize(__in UINT DesiredSize)
CheckedNumber< T, MaxValue > & operator+=(const CheckedNumber< T, MaxValue > &other)
void SetPrivateHeap(CDataBlockStore *pPrivateHeap)
HRESULT FindFirstMatchingValue(UINT Hash, CIterator *pIterator)
SHashEntry ** m_rgpHashEntries
HRESULT Reserve(UINT DesiredSize)
void GetNextEntry(CIterator *pIterator)
HRESULT Add(const T &var)
#define SAFE_DELETE_ARRAY(p)
HRESULT FindValueWithHash(T Data, UINT Hash, CIterator *pIterator)
void ClearWithoutDestructor()
HRESULT GetValue(T *pValue)
CheckedNumber< DWORD64, _UI64_MAX > CCheckedDword64
void SwapVector(CEffectVector< T > &vOther)
D3DX11INLINE UINT AlignToPowerOf2(UINT Value, UINT Alignment)
bool m_bOwnHashEntryArray
UINT FindIndexOf(void *pEntry) const
HRESULT AddValueWithHash(T Data, UINT Hash)
void QuickDelete(UINT index)
void GetFirstEntry(CIterator *pIterator)
HRESULT Grow(__in UINT DesiredSize, __in UINT ProvidedArraySize=0, __in_ecount_opt(ProvidedArraySize) void **ProvidedArray=NULL, __in bool OwnProvidedArray=false)
T & operator[](UINT index)
#define HASH_MIX(a, b, c)
CheckedNumber< T, MaxValue > & operator*=(const CheckedNumber< T, MaxValue > &other)
~CEffectHashTableWithPrivateHeap()
void Sort(int(__cdecl *pfnCompare)(const void *pElem1, const void *pElem2))
void RemoveEntry(CIterator *pIterator)
#define ANALYSIS_ASSUME(x)
CheckedNumber< UINT, _UI32_MAX > CCheckedDword
CheckedNumber< T, MaxValue > & operator*(const CheckedNumber< T, MaxValue > &other)
ID3D11Buffer D3D11_BUFFER_DESC void * pData
#define D3DXASSERT(condition)
CDataBlockStore * m_pPrivateHeap
D3DX11INLINE void dwordMemcpy(__out_bcount(uByteCount) void *__restrict pDest, __in_bcount(uByteCount) CONST void *__restrict pSource, UINT uByteCount)
BOOL PastEnd(CIterator *pIterator)
HRESULT CopyFrom(CEffectVector< T > &vOther)
CEffectHashTableWithPrivateHeap()
HRESULT Initialize(CEffectHashTable *pOther)
HRESULT InsertRange(const T *pVar, UINT index, UINT count)
HRESULT AddValueWithHash(T Data, UINT Hash)
HRESULT Insert(const T &var, UINT index)
CheckedNumber< T, MaxValue > & operator+(const CheckedNumber< T, MaxValue > &other)
HRESULT AddRange(const T *pVar, UINT count)