131 lines
2.4 KiB
C++
131 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <objidl.h>
|
|
|
|
const UINT PointerSetHashSize = 128;
|
|
|
|
struct PointerLinkedList
|
|
{
|
|
PVOID pKey;
|
|
PVOID pData;
|
|
PointerLinkedList* pNext;
|
|
};
|
|
|
|
class PointerSet
|
|
{
|
|
public:
|
|
PointerSet()
|
|
{
|
|
for(UINT i = 0; i < PointerSetHashSize; i++)
|
|
{
|
|
m_pHead[i] = NULL;
|
|
}
|
|
}
|
|
|
|
PVOID GetDataPtr(PVOID pKey)
|
|
{
|
|
PointerLinkedList* pThis = m_pHead[GetHash(pKey)];
|
|
while(pThis)
|
|
{
|
|
if(pThis->pKey == pKey)
|
|
{
|
|
return pThis->pData;
|
|
}
|
|
pThis = pThis->pNext;
|
|
}
|
|
return NULL;
|
|
}
|
|
bool AddMember(PVOID pKey, PVOID pData)
|
|
{
|
|
UINT Hash = GetHash(pKey);
|
|
PointerLinkedList* pThis = new PointerLinkedList;
|
|
if(pThis == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pThis->pNext = m_pHead[Hash];
|
|
pThis->pKey = pKey;
|
|
pThis->pData = pData;
|
|
m_pHead[Hash] = pThis;
|
|
return true;
|
|
}
|
|
bool DeleteMember(PVOID pKey)
|
|
{
|
|
UINT Hash = GetHash(pKey);
|
|
PointerLinkedList* pThis = m_pHead[Hash];
|
|
PointerLinkedList* pLast = 0L;
|
|
|
|
if( m_pHead[Hash]->pKey == pKey )
|
|
{
|
|
m_pHead[Hash] = pThis->pNext;
|
|
delete pThis;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
pLast = pThis;
|
|
pThis = pThis->pNext;
|
|
}
|
|
|
|
while( pThis )
|
|
{
|
|
if( pThis->pKey == pKey )
|
|
{
|
|
pLast->pNext = pThis->pNext;
|
|
delete pThis;
|
|
return true;
|
|
}
|
|
pLast = pThis;
|
|
pThis = pThis->pNext;
|
|
}
|
|
return false;
|
|
}
|
|
__forceinline UINT GetHash(PVOID pKey)
|
|
{
|
|
DWORD Key = (DWORD)pKey;
|
|
return (( Key >> 3 ^ Key >> 7 ^ Key >> 11 ^ Key >> 17 ) & (PointerSetHashSize - 1));
|
|
}
|
|
|
|
private:
|
|
PointerLinkedList* m_pHead[PointerSetHashSize];
|
|
};
|
|
|
|
|
|
class ThreadSafePointerSet : public PointerSet
|
|
{
|
|
public:
|
|
ThreadSafePointerSet()
|
|
{
|
|
InitializeCriticalSection(&m_CritSec);
|
|
}
|
|
~ThreadSafePointerSet()
|
|
{
|
|
DeleteCriticalSection(&m_CritSec);
|
|
}
|
|
PVOID GetDataPtr(PVOID pKey)
|
|
{
|
|
EnterCriticalSection(&m_CritSec);
|
|
PVOID p = PointerSet::GetDataPtr(pKey);
|
|
LeaveCriticalSection(&m_CritSec);
|
|
return p;
|
|
}
|
|
bool AddMember(PVOID pKey, PVOID pData)
|
|
{
|
|
EnterCriticalSection(&m_CritSec);
|
|
bool Result = PointerSet::AddMember(pKey, pData);
|
|
LeaveCriticalSection(&m_CritSec);
|
|
return Result;
|
|
}
|
|
bool DeleteMember(PVOID pKey)
|
|
{
|
|
EnterCriticalSection(&m_CritSec);
|
|
bool Result = PointerSet::DeleteMember(pKey);
|
|
LeaveCriticalSection(&m_CritSec);
|
|
return Result;
|
|
}
|
|
|
|
private:
|
|
CRITICAL_SECTION m_CritSec;
|
|
};
|