📄 clookasidelist.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 + -