windows-nt/Source/XPSP1/NT/ds/security/passport/include/bstrhash.h
2020-09-26 16:20:57 +08:00

156 lines
4 KiB
C++

// Helper funcs for string maps
#ifndef _BSTRHASH_INC
#define _BSTRHASH_INC
#pragma warning( disable : 4786 )
#include <map>
using namespace std;
#include "lkrhash.h"
template <class _Key, class _Val>
class CLKWrap
{
public:
#ifdef MEM_DBG
char m_id[8];
#endif
_Key m_k;
_Val m_v;
mutable LONG m_cRefs;
CLKWrap(_Key k, _Val v, char* id = "CLKWrap") : m_k(k), m_v(v), m_cRefs(0)
{
#ifdef MEM_DBG
memcpy(m_id, id, 8);
#endif
}
~CLKWrap()
{
}
};
template <class _Val>
class CRawCIBstrHash
: public CTypedHashTable<CRawCIBstrHash<_Val>, const CLKWrap<BSTR,_Val>, BSTR>
{
public:
typedef CLKWrap<BSTR,_Val> ValueType;
CRawCIBstrHash(LPCSTR name) :
CTypedHashTable<CRawCIBstrHash, const CLKWrap<BSTR,_Val>, BSTR>(name)
{}
CRawCIBstrHash(LPCSTR name, double maxload, DWORD initsize, DWORD num_subtbls) :
CTypedHashTable<CRawCIBstrHash, const CLKWrap<BSTR,_Val>, BSTR>(name,maxload,initsize,num_subtbls)
{}
static BSTR ExtractKey(const CLKWrap<BSTR,_Val> *pEntry)
{ return pEntry->m_k; }
static DWORD CalcKeyHash(BSTR pstrKey)
{ return HashStringNoCase(pstrKey); }
static bool EqualKeys(BSTR x, BSTR y)
{
if (x == NULL)
{
return (y==NULL ? TRUE : FALSE);
}
if (!y) return FALSE;
return (_wcsicmp(x,y) == 0);
}
static void AddRefRecord(const CLKWrap<BSTR,_Val>* pTest, int nIncr)
{
IRTLTRACE(_TEXT("AddRef(%p, %s) %d, cRefs == %d\n"),
pTest, pTest->m_k, nIncr, pTest->m_cRefs);
if (nIncr == +1)
{
// or, perhaps, pIFoo->AddRef() (watch out for marshalling)
// or ++pTest->m_cRefs (single-threaded only)
InterlockedIncrement(&pTest->m_cRefs);
}
else if (nIncr == -1)
{
// or, perhaps, pIFoo->Release() or --pTest->m_cRefs;
LONG l = InterlockedDecrement(&pTest->m_cRefs);
// For some hashtables, it may also make sense to add the following
if (l == 0) delete pTest;
// but that would typically only apply when InsertRecord was
// used thus
// lkrc = ht.InsertRecord(new CTest(foo, bar));
}
else
IRTLASSERT(0);
}
};
// For normal built in types as keys
template <class _Key,class _Val>
class CGenericHash
: public CTypedHashTable<CGenericHash<_Key,_Val>, const CLKWrap<_Key,_Val>, _Key>
{
public:
typedef CLKWrap<_Key,_Val> ValueType;
CGenericHash(LPCSTR name) :
CTypedHashTable<CGenericHash, const ValueType, _Key>(name)
{}
CGenericHash(LPCSTR name, double maxload, DWORD initsize, DWORD num_subtbls) :
CTypedHashTable<CGenericHash, const ValueType, _Key>(name,maxload,initsize,num_subtbls)
{}
static _Key ExtractKey(const CLKWrap<_Key,_Val> *pEntry)
{ return pEntry->m_k; }
static DWORD CalcKeyHash(_Key psKey)
{ return Hash(psKey); }
static bool EqualKeys(_Key x, _Key y)
{ return (x==y); }
static void AddRefRecord(const CLKWrap<_Key,_Val>* pTest, int nIncr)
{
IRTLTRACE(_TEXT("AddRef(%p, %s) %d, cRefs == %d\n"),
pTest, pTest->m_k, nIncr, pTest->m_cRefs);
if (nIncr == +1)
{
// or, perhaps, pIFoo->AddRef() (watch out for marshalling)
// or ++pTest->m_cRefs (single-threaded only)
InterlockedIncrement(&pTest->m_cRefs);
}
else if (nIncr == -1)
{
// or, perhaps, pIFoo->Release() or --pTest->m_cRefs;
LONG l = InterlockedDecrement(&pTest->m_cRefs);
// For some hashtables, it may also make sense to add the following
if (l == 0) delete pTest;
// but that would typically only apply when InsertRecord was
// used thus
// lkrc = ht.InsertRecord(new CTest(foo, bar));
}
else
IRTLASSERT(0);
}
};
#include <map>
using namespace std;
class RawBstrLT
{
public:
bool operator()(const BSTR& x, const BSTR& y) const
{
return (_wcsicmp(x,y) < 0);
}
};
#endif