You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.9 KiB
184 lines
4.9 KiB
#pragma once
|
|
|
|
#include <tlist.h>
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Hash table entry.
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
template<class T, class V> class THashTableEntry
|
|
{
|
|
public:
|
|
|
|
DWORD _dwSig;
|
|
HRESULT _hr;
|
|
|
|
T _tKey;
|
|
V _vItem;
|
|
DWORD _dwHash;
|
|
|
|
THashTableEntry(T& tKey, V& vItem);
|
|
~THashTableEntry();
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTableEntry ctor
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> THashTableEntry<T, V>::THashTableEntry(T& tKey, V& vItem)
|
|
: _hr(S_OK), _dwSig('RTNE')
|
|
{
|
|
IF_FAILED_EXIT(_tKey.Assign(tKey));
|
|
|
|
IF_FAILED_EXIT(_vItem.Assign(vItem));
|
|
|
|
IF_FAILED_EXIT(_tKey.GetHash(&_dwHash, T::CaseSensitive));
|
|
|
|
exit:
|
|
|
|
return;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTableEntry dtor
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> THashTableEntry<T, V>::~THashTableEntry()
|
|
{ }
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Hash table class
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
template<class T, class V> class THashTable
|
|
{
|
|
public:
|
|
|
|
THashTable();
|
|
THashTable(DWORD nSlots);
|
|
~THashTable();
|
|
|
|
HRESULT Init(DWORD nSlots);
|
|
HRESULT Destruct();
|
|
HRESULT Insert(T& tKey, V& vItem);
|
|
HRESULT Retrieve(T& tKey, V** ppvItem);
|
|
|
|
private:
|
|
|
|
HRESULT _hr;
|
|
DWORD _dwSig;
|
|
DWORD _nSlots;
|
|
TList<THashTableEntry<T, V> *> *_pListArray;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable ctor
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> THashTable<T, V>::THashTable()
|
|
: _hr(S_OK), _dwSig('HSAH'), _nSlots(0), _pListArray(NULL)
|
|
{}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable ctor
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> THashTable<T, V>::THashTable(DWORD nSlots)
|
|
: THashTable()
|
|
{
|
|
Init(nSlots);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable dtor
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> THashTable<T, V>::~THashTable(void)
|
|
{
|
|
Destruct();
|
|
SAFEDELETEARRAY(_pListArray);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable::Init
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> HRESULT THashTable<T, V>::Init(DWORD nSlots)
|
|
{
|
|
_nSlots = nSlots;
|
|
|
|
_pListArray = new TList<THashTableEntry<T, V> * > [_nSlots];
|
|
|
|
IF_ALLOC_FAILED_EXIT((_pListArray));
|
|
|
|
exit:
|
|
|
|
return _hr;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable::Insert
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> HRESULT THashTable<T, V>::Insert(T& tKey, V& vItem)
|
|
{
|
|
_hr = S_OK;
|
|
|
|
THashTableEntry<T, V> *pEntry = new THashTableEntry<T, V>(tKey, vItem);
|
|
|
|
IF_ALLOC_FAILED_EXIT(pEntry);
|
|
|
|
IF_FALSE_EXIT((pEntry->_hr == S_OK), pEntry->_hr);
|
|
|
|
IF_FAILED_EXIT(_pListArray[(pEntry->_dwHash) % _nSlots].Insert(pEntry));
|
|
|
|
exit:
|
|
|
|
return _hr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable::Retrieve
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> HRESULT THashTable<T, V>::Retrieve(T& tKey, V** ppvItem)
|
|
{
|
|
_hr = S_OK;
|
|
|
|
DWORD dwHash = 0;
|
|
BOOL bFound = FALSE;
|
|
|
|
THashTableEntry<T, V> **ppEntry = 0;
|
|
|
|
tKey.GetHash(&dwHash, T::CaseSensitive);
|
|
|
|
TList_Iter<THashTableEntry<T, V> * > Iterator(_pListArray[dwHash % _nSlots]);
|
|
|
|
while (ppEntry = Iterator.Next())
|
|
{
|
|
if (dwHash != ((*ppEntry)->_dwHash))
|
|
continue;
|
|
|
|
IF_FAILED_EXIT(tKey.CompareString((*ppEntry)->_tKey));
|
|
|
|
if (_hr == S_OK)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
|
|
*ppvItem = bFound ? &((*ppEntry)->_vItem) : NULL;
|
|
_hr = bFound ? S_OK : S_FALSE;
|
|
|
|
return _hr;
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// THashTable::Destruct
|
|
//-----------------------------------------------------------------------------
|
|
template<class T, class V> HRESULT THashTable<T, V>::Destruct()
|
|
{
|
|
for (DWORD i = 0; i < _nSlots; i++)
|
|
_pListArray[i].Destruct();
|
|
|
|
return S_OK;
|
|
}
|
|
|