⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chashtable.h

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 H
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CHashTable.h,v 1.4 2002/08/06 20:10:37 dallen Exp $
____________________________________________________________________________*/

#ifndef Included_CHashTable_h	// [
#define Included_CHashTable_h

#include "pgpClassesConfig.h"

#include "CArray.h"
#include "CErrorState.h"
#include "CList.h"

_PGP_BEGIN

// Class CHashTable

template <typename T> class CHashTable SMART_ERROR_INHERIT
{
private:
	struct HashTablePair : public CListableObject<HashTablePair>
	{
		PGPUInt32	key;
		T			*pItem;
	};

public:
	CHashTable(PGPUInt32 size);
	~CHashTable();

	PGPUInt32	Population() const {mPopulation;}
	PGPUInt32	Size() const {return mSize;}

	T *		Lookup(PGPUInt32 key) const;

	SMART_ERROR	Add(PGPUInt32 key, T *pItem);
	void		Remove(PGPUInt32 key);

	void	Empty();

private:
	CArray< CList<HashTablePair> * >	mTable;

	PGPUInt32	mSize;
	PGPUInt32	mPopulation;

	PGPUInt32		Hash(PGPUInt32 key) const;
	HashTablePair *	FindPairInList(PGPUInt32 i, PGPUInt32 key) const;
};


// CHashTable template member functions

template <typename T>
CHashTable<T>::CHashTable(PGPUInt32 size) : 
	mTable(size), mSize(size), mPopulation(0)
{
#if PGP_EXCEPTIONS

	mTable.Wipe();

#else	// !PGP_EXCEPTIONS

	Status() = mTable.Status();

	if (Status().IsntError())
		mTable.Wipe();

#endif	// !PGP_EXCEPTIONS
}

template <typename T> 
CHashTable<T>::~CHashTable()
{
	Empty();
}

template <typename T>
T * 
CHashTable<T>::Lookup(PGPUInt32 key) const
{
	PGPUInt32	i	= Hash(key);

	if (IsNull(mTable[i]))
		return NULL;

	HashTablePair	*pPair	= FindPairInList(i, key);

	if (IsNull(pPair))
		return NULL;
	else
		return pPair->pItem;
}

template <typename T>
SMART_ERROR 
CHashTable<T>::Add(PGPUInt32 key, T *pItem)
{
	pgpAssert(IsNull(Lookup(key)));

	SMART_ERROR_DECLARE
	PGPUInt32	i	= Hash(key);

	if (IsNull(mTable[i]))
		mTable[i] = new CList<HashTablePair>;

#if PGP_EXCEPTIONS

	try
	{
		HashTablePair	*pPair	= new HashTablePair;

		pPair->key = key;
		pPair->pItem = pItem;

		mTable[i]->AddTail(pPair);
	}
	catch (CComboError&)
	{
		delete mTable[i];
		mTable[i] = NULL;

		throw;
	}

#else	// !PGP_EXCEPTIONS

	if (IsNull(mTable[i]))
		error.pgpErr = kPGPError_OutOfMemory;

	if (error.IsntError())
	{
		HashTablePair	*pPair	= new HashTablePair;

		if (IsNull(pPair))
			error.pgpErr = kPGPError_OutOfMemory;

		if (error.IsntError())
		{
			pPair->key = key;
			pPair->pItem = pItem;

			mTable[i]->AddTail(pPair);
		}

		if (error.IsError())
		{
			delete mTable[i];
			mTable[i] = NULL;
		}
	}

#endif	// PGP_EXCEPTIONS

	SMART_ERROR_RETURN
}

template <typename T>
void 
CHashTable<T>::Empty()
{
	for (PGPUInt32 i = 0; i < Size(); i++)
	{
		if (IsntNull(mTable[i]))
		{
			mTable[i]->EmptyWithDelete();

			delete mTable[i];
			mTable[i] = NULL;
		}
	}
}

template <typename T>
void 
CHashTable<T>::Remove(PGPUInt32 key)
{
	pgpAssert(IsntNull(Lookup(key)));

	PGPUInt32		i		= Hash(key);
	HashTablePair	*pPair	= FindPairInList(i, key);

	mTable[i]->Remove(pPair);
	delete pPair;

	if (mTable[i]->IsEmpty())
	{
		delete mTable[i];
		mTable[i] = NULL;
	}
}

template <typename T>
PGPUInt32 
CHashTable<T>::Hash(PGPUInt32 key) const
{
	return ((key >> 4) % (Size() - 1));
}

template <typename T>
CHashTable<T>::HashTablePair * 
CHashTable<T>::FindPairInList(PGPUInt32 i, PGPUInt32 key) const
{
	HashTablePair	*pPair	= mTable[i]->Head();

	while (IsntNull(pPair))
	{
		if (pPair->key == key)
			break;

		pPair = mTable[i]->Next(pPair);
	}

	return pPair;
}

_PGP_END

#endif	// ] Included_CHashTable_h

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -