初步修复
This commit is contained in:
parent
8fc4357cc6
commit
e4714f3f0e
46705 changed files with 12004901 additions and 0 deletions
318
Server/ServiceMonitorEx/External/UltimateToolbox/source/OXHashTable.cpp
vendored
Normal file
318
Server/ServiceMonitorEx/External/UltimateToolbox/source/OXHashTable.cpp
vendored
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
// HashTable.cpp: implementation of the COXHashTable class.
|
||||
//
|
||||
// Simple hash table class based on code in K&R's "The C programming
|
||||
// language".
|
||||
//
|
||||
// Author: Chris Maunder
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Version: 9.3
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "OXHashTable.h"
|
||||
|
||||
#include <malloc.h> // for free() (needed becuase of strdup())
|
||||
|
||||
// TODO: add API to traverse elements (FindFirst, FindNext and Count)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// HashNode structure - auto initialise and cleanup
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
HashNode::HashNode()
|
||||
{
|
||||
szName = NULL;
|
||||
pNext = NULL;
|
||||
dwData = 0;
|
||||
}
|
||||
|
||||
HashNode::~HashNode()
|
||||
{
|
||||
if (szName)
|
||||
free(szName);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// COXHashTable - Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
COXHashTable::COXHashTable(int nHashTableSize)
|
||||
{
|
||||
CommonConstruct(nHashTableSize);
|
||||
}
|
||||
|
||||
COXHashTable::COXHashTable()
|
||||
{
|
||||
CommonConstruct(67);
|
||||
}
|
||||
|
||||
BOOL COXHashTable::CommonConstruct(int nHashTableSize)
|
||||
{
|
||||
m_pHashTable = NULL;
|
||||
m_nHashTableSize = 0;
|
||||
m_bCaseSensitive = FALSE;
|
||||
|
||||
return InitHashTable(nHashTableSize);
|
||||
}
|
||||
|
||||
COXHashTable::~COXHashTable()
|
||||
{
|
||||
RemoveAll();
|
||||
delete [] m_pHashTable;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// COXHashTable - Public Attributes
|
||||
|
||||
void COXHashTable::SetCaseSensitive(BOOL bCase)
|
||||
{
|
||||
m_bCaseSensitive = bCase;
|
||||
}
|
||||
|
||||
BOOL COXHashTable::GetCaseSensitive()
|
||||
{
|
||||
return m_bCaseSensitive;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// COXHashTable - Public Operations
|
||||
|
||||
BOOL COXHashTable::InitHashTable(UINT nHashSize)
|
||||
{
|
||||
if (nHashSize < 1)
|
||||
return FALSE;
|
||||
|
||||
RemoveAll();
|
||||
delete [] m_pHashTable;
|
||||
|
||||
m_nHashTableSize = nHashSize;
|
||||
m_pHashTable = new HashNode*[m_nHashTableSize];
|
||||
if (!m_pHashTable)
|
||||
return FALSE;
|
||||
|
||||
for (UINT i = 0; i < m_nHashTableSize; i++)
|
||||
m_pHashTable[i] = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT COXHashTable::GetHashTableSize() const
|
||||
{
|
||||
return m_nHashTableSize;
|
||||
}
|
||||
|
||||
void COXHashTable::RemoveAll()
|
||||
{
|
||||
if (!m_pHashTable)
|
||||
return;
|
||||
|
||||
for (UINT i = 0; i < m_nHashTableSize; i++)
|
||||
{
|
||||
HashNode* pPrev = NULL;
|
||||
HashNode* pNext = m_pHashTable[i];
|
||||
|
||||
while (pNext)
|
||||
{
|
||||
pPrev = pNext->pNext;
|
||||
delete pNext;
|
||||
pNext = pPrev;
|
||||
}
|
||||
|
||||
m_pHashTable[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL COXHashTable::Add(LPCTSTR sz, DWORD dwData)
|
||||
{
|
||||
HashNode *pNode = Lookup(sz);
|
||||
|
||||
// Can't find entry - so add a new one
|
||||
if (pNode == NULL)
|
||||
{
|
||||
// Create a new node with the given name
|
||||
pNode = new HashNode;
|
||||
|
||||
if (pNode == NULL)
|
||||
return FALSE;
|
||||
|
||||
// Copy over the string
|
||||
pNode->szName = _tcsdup(sz);
|
||||
if (pNode->szName == NULL)
|
||||
{
|
||||
delete pNode;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Find it's position in the hash table and insert it at the head of the
|
||||
// list at that point
|
||||
pNode->nHashValue = Hash(sz);
|
||||
pNode->pNext = m_pHashTable[pNode->nHashValue];
|
||||
m_pHashTable[pNode->nHashValue] = pNode;
|
||||
}
|
||||
|
||||
// Set the data
|
||||
pNode->dwData = dwData;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL COXHashTable::Lookup(LPCTSTR sz, DWORD& dwData) const
|
||||
{
|
||||
dwData = 0;
|
||||
HashNode *pNode = Lookup(sz);
|
||||
if (!pNode)
|
||||
return FALSE;
|
||||
|
||||
dwData = pNode->dwData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL COXHashTable::Remove(LPCTSTR sz)
|
||||
{
|
||||
HashNode *pNode, *pPrev = NULL;
|
||||
UINT nHashVal = Hash(sz);
|
||||
|
||||
for (pNode = m_pHashTable[nHashVal]; pNode != NULL; pNode = pNode->pNext)
|
||||
{
|
||||
BOOL bFound = FALSE;
|
||||
|
||||
if (m_bCaseSensitive)
|
||||
bFound = (_tcscmp(sz, pNode->szName) == 0);
|
||||
else
|
||||
bFound = (_tcsicmp(sz, pNode->szName) == 0);
|
||||
|
||||
if (bFound)
|
||||
break;
|
||||
|
||||
pPrev = pNode;
|
||||
}
|
||||
|
||||
// No entry found
|
||||
if (pNode == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (pPrev == NULL) // Entry is first entry at Hash table entry site
|
||||
{
|
||||
m_pHashTable[nHashVal] = pNode->pNext;
|
||||
delete pNode;
|
||||
}
|
||||
else // More than one entry with this hash val - remove entry from list
|
||||
{
|
||||
pPrev->pNext = pNode->pNext;
|
||||
delete pNode;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// COXHashTable - protected implementation
|
||||
|
||||
UINT COXHashTable::Hash(LPCTSTR sz) const
|
||||
{
|
||||
UINT nHashVal = 0;
|
||||
|
||||
if (m_bCaseSensitive)
|
||||
{
|
||||
while (*sz)
|
||||
nHashVal = (nHashVal<<5) + nHashVal + *sz++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*sz)
|
||||
{
|
||||
if (_istupper(*sz))
|
||||
nHashVal = (nHashVal<<5) + nHashVal + _tolower(*sz++);
|
||||
else
|
||||
nHashVal = (nHashVal<<5) + nHashVal + *sz++;
|
||||
}
|
||||
}
|
||||
|
||||
return nHashVal % m_nHashTableSize;
|
||||
}
|
||||
|
||||
HashNode *COXHashTable::Lookup(LPCTSTR sz) const
|
||||
{
|
||||
HashNode *pNode;
|
||||
UINT nHashVal = Hash(sz);
|
||||
|
||||
for (pNode = m_pHashTable[nHashVal]; pNode != NULL; pNode = pNode->pNext)
|
||||
{
|
||||
BOOL bFound = FALSE;
|
||||
|
||||
if (m_bCaseSensitive)
|
||||
bFound = (_tcscmp(sz, pNode->szName) == 0);
|
||||
else
|
||||
bFound = (_tcsicmp(sz, pNode->szName) == 0);
|
||||
|
||||
if (bFound)
|
||||
return pNode;
|
||||
}
|
||||
|
||||
// Did not find.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HASH_POS COXHashTable::GetStartPosition() const
|
||||
{
|
||||
if (!m_pHashTable)
|
||||
return NULL;
|
||||
|
||||
// Check there are elements
|
||||
for (UINT nNode = 0; nNode < m_nHashTableSize; nNode++)
|
||||
if (m_pHashTable[nNode])
|
||||
return HASHTABLE_START_POS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void COXHashTable::GetNextAssoc(HASH_POS& pos, LPCTSTR& sz, DWORD& dwData) const
|
||||
{
|
||||
if (!m_pHashTable || !pos)
|
||||
{
|
||||
pos = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is the first call, then find the first item
|
||||
if (pos == HASHTABLE_START_POS)
|
||||
{
|
||||
pos = NULL;
|
||||
for (UINT nNode = 0; nNode < m_nHashTableSize; nNode++)
|
||||
{
|
||||
if (m_pHashTable[nNode])
|
||||
{
|
||||
pos = m_pHashTable[nNode];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fill in return data
|
||||
if (pos)
|
||||
{
|
||||
sz = pos->szName;
|
||||
dwData = pos->dwData;
|
||||
}
|
||||
|
||||
// Find the next item
|
||||
if (pos)
|
||||
{
|
||||
HashNode* pNode = (HashNode*) pos;
|
||||
if (pNode->pNext == NULL)
|
||||
{
|
||||
pos = NULL;
|
||||
for (UINT nNode = pNode->nHashValue+1; nNode < m_nHashTableSize; nNode++)
|
||||
{
|
||||
if (m_pHashTable[nNode])
|
||||
{
|
||||
pos = m_pHashTable[nNode];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
pos = pNode->pNext;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue