|
|
// 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
|