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

📄 clookasidelist.h

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

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

#ifndef Included_CLookasideList_h	// [
#define Included_CLookasideList_h

#include "pgpClassesConfig.h"

#include "CErrorState.h"
#include "CArray.h"
#include "CSpinLock.h"

_PGP_BEGIN

// Class CLookasideList

template <typename T> class CLookasideList SMART_ERROR_INHERIT
{
	NOT_COPYABLE(CLookasideList)

public:
	enum {kDefaultLookasideDepth = 8};

	CLookasideList(PGPUInt32 depth = kDefaultLookasideDepth);
	~CLookasideList();

	PGPUInt32	Count() const {return mCount;}
	PGPUInt32	Depth() const {return mDepth;}

#if PGP_EXCEPTIONS
	T *			Allocate();
#else	// !PGP_EXCEPTIONS
	CComboError	Allocate(T *&pItem);
#endif	// PGP_EXCEPTIONS

	void	Free(T *pItem);
	void	Clear();

private:
	CArray<PGPByte *>	mFreeItems;
	CSpinLock			mFreeItemsLock;

	PGPUInt32	mCount;
	PGPUInt32	mDepth;
};


// Class CLookasideList template member functions

template <typename T> 
CLookasideList<T>::CLookasideList(PGPUInt32 depth) : 
	mFreeItems(depth), mCount(0), mDepth(depth)
{
#if PGP_EXCEPTIONS

	mFreeItems.Wipe();

#else	// !PGP_EXCEPTIONS

	Status() = mFreeItems.Status();

	if (Status().IsntError())
		Status() = mFreeItemsLock.Status();

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

#endif	// !PGP_EXCEPTIONS
}

template <typename T> 
CLookasideList<T>::~CLookasideList()
{
	Clear();
}

template <typename T> 
#if PGP_EXCEPTIONS
T * 
CLookasideList<T>::Allocate()
#else	// !PGP_EXCEPTIONS
CComboError 
CLookasideList<T>::Allocate(T *&pItem)
#endif	// PGP_EXCEPTIONS
{
	SMART_ERROR_DECLARE
	PGPByte	*pRawMem	= NULL;

	mFreeItemsLock.Lock();

	if (Count() > 0)
	{
		// Take item from free array.
		for (PGPUInt32 i = 0; i < Depth(); i++)
		{
			if (IsntNull(mFreeItems[i]))
			{
				pRawMem = mFreeItems[i];
				mFreeItems[i] = NULL;

				break;
			}
		}

		mCount--;
		mFreeItemsLock.Unlock();
	}
	else
	{
		// Allocate raw memory for new item.
		mFreeItemsLock.Unlock();
		pRawMem = new (std::nothrow) PGPByte[sizeof(T)];
	}

	// Use placement new to call constructor (!!!).
#if PGP_EXCEPTIONS

	if (IsNull(pRawMem))
		THROW_PGPERROR(kPGPError_OutOfMemory);

	try
	{
		return new (static_cast<void *>(pRawMem)) T;
	}
	catch (CComboError&)
	{
		delete[] pRawMem;
		throw;
	}

#else	// !PGP_EXCEPTIONS

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

	if (error.IsntError())
		pItem = new (static_cast<void *>(pRawMem)) T;

#endif	// PGP_EXCEPTIONS

	SMART_ERROR_RETURN
}

template <typename T> 
void 
CLookasideList<T>::Free(T *pItem)
{
	pgpAssertAddrValid(pItem, VoidAlign);

	// Call the destructor (!!!).
	pItem->~T();

	mFreeItemsLock.Lock();

	if (Count() < Depth())
	{
		// Find space in free array for item.
		for (PGPUInt32 i = 0; i < Depth(); i++)
		{
			if (IsNull(mFreeItems[i]))
			{
				mFreeItems[i] = reinterpret_cast<PGPByte *>(pItem);
				break;
			}
		}

		mCount++;
		mFreeItemsLock.Unlock();
	}
	else
	{
		// Just free the memory block.
		mFreeItemsLock.Unlock();
		delete[] reinterpret_cast<PGPByte *>(pItem);
	}
}

template <typename T> 
void 
CLookasideList<T>::Clear()
{
	mFreeItemsLock.Lock();

	for (PGPUInt32 i = 0; i < Depth(); i++)
	{
		if (IsntNull(mFreeItems[i]))
		{
			delete[] mFreeItems[i];
			mFreeItems[i] = NULL;
		}
	}

	mCount = 0;
	mFreeItemsLock.Unlock();
}

_PGP_END

#endif	// ] Included_CLookasideList_h

⌨️ 快捷键说明

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