143 lines
4.3 KiB
C
143 lines
4.3 KiB
C
|
/*---------------------------------------------------------------------------
|
||
|
File: VarMap.h
|
||
|
|
||
|
Comments: A map string=>Variant, used by VarSet. It is implemented as a hash
|
||
|
table, win and optional red-black tree index.
|
||
|
|
||
|
Added features include:
|
||
|
CaseSensitive property - The case of each key is preserved as it was when
|
||
|
the key was first added to the map. The hash function is not case sensitive,
|
||
|
so the CaseSensitive property can be toggled on and off without rehashing the data.
|
||
|
|
||
|
Optional indexing to allow for fast enumeration in alphabetical order by key.
|
||
|
This will add overhead to insert operations. Without indexing, the contents of
|
||
|
the map can be enumerated, but they will be in arbitrary order.
|
||
|
|
||
|
Stream I/O functions for persistance.
|
||
|
|
||
|
(c) Copyright 1995-1998, Mission Critical Software, Inc., All Rights Reserved
|
||
|
Proprietary and confidential to Mission Critical Software, Inc.
|
||
|
|
||
|
REVISION LOG ENTRY
|
||
|
Revision By: Christy Boles
|
||
|
Revised on 11/19/98 18:03:19
|
||
|
|
||
|
---------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
#ifndef __VARSETMAP_H
|
||
|
#define __VARSETMAP_H
|
||
|
|
||
|
#include "VarData.h"
|
||
|
#include "VarNdx.h"
|
||
|
|
||
|
class CHashItem // used internally by hash table
|
||
|
{
|
||
|
friend class CMapStringToVar;
|
||
|
friend class CIndexItem;
|
||
|
|
||
|
CHashItem() { pNext = NULL; value = NULL; pIndex = NULL; }
|
||
|
|
||
|
CHashItem* pNext; // used in hash table
|
||
|
UINT nHashValue; // needed for efficient iteration
|
||
|
CString key;
|
||
|
CVarData* value;
|
||
|
CIndexItem* pIndex; // pointer to index, or NULL
|
||
|
};
|
||
|
|
||
|
class CMapStringToVar : public CObject
|
||
|
{
|
||
|
DECLARE_SERIAL(CMapStringToVar)
|
||
|
public:
|
||
|
|
||
|
// Construction
|
||
|
CMapStringToVar(BOOL isCaseSensitive,BOOL isIndexed, BOOL allowRehash, int nBlockSize = 10);
|
||
|
protected:
|
||
|
CMapStringToVar() {};
|
||
|
public:
|
||
|
// Attributes
|
||
|
// number of elements
|
||
|
int GetCount() const { return m_nCount; }
|
||
|
BOOL IsEmpty() const { return m_nCount == 0; }
|
||
|
|
||
|
// Lookup
|
||
|
BOOL Lookup(LPCTSTR key, CVarData*& rValue) const;
|
||
|
BOOL LookupKey(LPCTSTR key, LPCTSTR& rKey) const;
|
||
|
|
||
|
// Operations
|
||
|
// Lookup and add if not there
|
||
|
CVarData*& operator[](LPCTSTR key);
|
||
|
|
||
|
// add a new (key, value) pair
|
||
|
void SetAt(LPCTSTR key, CVarData* newValue) { (*this)[key] = newValue; }
|
||
|
|
||
|
|
||
|
BOOL RemoveKey(LPCTSTR key);
|
||
|
void RemoveAll();
|
||
|
|
||
|
POSITION GetStartPosition() const { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
|
||
|
void GetNextAssoc(POSITION& rNextPosition, CString& rKey, CVarData*& rValue) const;
|
||
|
POSITION GetPositionAt(LPCTSTR key) { UINT hash; return (POSITION)GetAssocAt(key,hash); }
|
||
|
CIndexItem * GetIndexAt(LPCTSTR key) { UINT hash; CHashItem * h = GetAssocAt(key,hash); if ( h ) return h->pIndex; else return NULL; }
|
||
|
|
||
|
UINT GetHashTableSize() const { return m_nHashTableSize; }
|
||
|
void InitHashTable(UINT hashSize, BOOL bAllocNow = TRUE);
|
||
|
|
||
|
UINT HashKey(LPCTSTR key) const;
|
||
|
|
||
|
void SetCaseSensitive(BOOL val) { m_CaseSensitive = val;
|
||
|
m_Index.SetCompareFunctions(val? &CompareItems : &CompareItemsNoCase,
|
||
|
val? CompareStringToItem : CompareStringToItemNoCase); }
|
||
|
|
||
|
void SetIndexed(BOOL val);
|
||
|
|
||
|
void SetAllowRehash(BOOL val) { m_AllowRehash = val; }
|
||
|
|
||
|
HRESULT ReadFromStream(LPSTREAM pStm);
|
||
|
HRESULT WriteToStream(LPSTREAM pStm);
|
||
|
DWORD CalculateStreamedLength();
|
||
|
long CountItems();
|
||
|
|
||
|
CIndexTree * GetIndex() { if ( m_Indexed ) return &m_Index; else return NULL; }
|
||
|
|
||
|
void McLogInternalDiagnostics(CString keyName);
|
||
|
|
||
|
|
||
|
// Implementation
|
||
|
protected:
|
||
|
// Hash table stuff
|
||
|
CHashItem** m_pHashTable;
|
||
|
UINT m_nHashTableSize;
|
||
|
UINT m_nCount;
|
||
|
CHashItem* m_pFreeList;
|
||
|
struct CPlex* m_pBlocks;
|
||
|
int m_nBlockSize;
|
||
|
|
||
|
CHashItem* NewAssoc();
|
||
|
void FreeAssoc(CHashItem*);
|
||
|
CHashItem* GetAssocAt(LPCTSTR, UINT&) const;
|
||
|
void BuildIndex();
|
||
|
void ResizeTable();
|
||
|
|
||
|
BOOL m_CaseSensitive;
|
||
|
BOOL m_Indexed;
|
||
|
BOOL m_AllowRehash;
|
||
|
CIndexTree m_Index;
|
||
|
|
||
|
public:
|
||
|
~CMapStringToVar();
|
||
|
|
||
|
void Serialize(CArchive&);
|
||
|
#ifdef _DEBUG
|
||
|
void Dump(CDumpContext&) const;
|
||
|
void AssertValid() const;
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////
|
||
|
#endif // __VARSETMAP
|