248 lines
4.8 KiB
C++
248 lines
4.8 KiB
C++
/* Copyright (C) John W. Ratcliff, 2001.
|
|
* All rights reserved worldwide.
|
|
*
|
|
* This software is provided "as is" without express or implied
|
|
* warranties. You may freely copy and compile this source into
|
|
* applications you distribute provided that the copyright text
|
|
* below is included in the resulting source code, for example:
|
|
* "Portions Copyright (C) John W. Ratcliff, 2001"
|
|
*/
|
|
#pragma once
|
|
|
|
/***********************************************************************/
|
|
/** POOL : Template class to manage a fixed pool of items for */
|
|
/** extremely fast allocation and deallocation. */
|
|
/** */
|
|
/** Written by John W. Ratcliff jratcliff@att.net */
|
|
/***********************************************************************/
|
|
|
|
template <class Type> class Pool
|
|
{
|
|
public:
|
|
Pool(void)
|
|
{
|
|
mHead = 0;
|
|
mFree = 0;
|
|
mData = 0;
|
|
mCurrent = 0;
|
|
mFreeCount = 0;
|
|
mUsedCount = 0;
|
|
};
|
|
|
|
~Pool(void)
|
|
{
|
|
if (mData)
|
|
delete [] mData;
|
|
};
|
|
|
|
|
|
void Release(void)
|
|
{
|
|
if (mData)
|
|
delete [] mData;
|
|
|
|
mHead = 0;
|
|
mFree = 0;
|
|
|
|
mData = 0;
|
|
mCurrent = 0;
|
|
mFreeCount = 0;
|
|
mUsedCount = 0;
|
|
};
|
|
|
|
void Set(int maxitems)
|
|
{
|
|
if (mData)
|
|
delete [] mData; // delete any previous incarnation.
|
|
mMaxItems = maxitems;
|
|
mData = new Type[mMaxItems];
|
|
mFree = mData;
|
|
mHead = 0;
|
|
int loopValue = (mMaxItems-1);
|
|
for (int i=0; i<loopValue; i++)
|
|
{
|
|
mData[i].SetNext( &mData[i+1] );
|
|
if ( i == 0 )
|
|
mData[i].SetPrevious( 0 );
|
|
else
|
|
mData[i].SetPrevious( &mData[i-1] );
|
|
}
|
|
|
|
mData[loopValue].SetNext(0);
|
|
mData[loopValue].SetPrevious( &mData[loopValue-1] );
|
|
mCurrent = 0; // there is no current, currently. <g>
|
|
mFreeCount = maxitems;
|
|
mUsedCount = 0;
|
|
};
|
|
|
|
|
|
Type * GetNext(bool &looped)
|
|
{
|
|
|
|
looped = false; //default value
|
|
|
|
if ( !mHead ) return 0; // there is no data to process.
|
|
Type *ret;
|
|
|
|
if ( !mCurrent )
|
|
{
|
|
ret = mHead;
|
|
looped = true;
|
|
}
|
|
else
|
|
{
|
|
ret = mCurrent;
|
|
}
|
|
|
|
if ( ret ) mCurrent = ret->GetNext();
|
|
|
|
|
|
return ret;
|
|
};
|
|
|
|
bool IsEmpty(void) const
|
|
{
|
|
if ( !mHead ) return true;
|
|
return false;
|
|
};
|
|
|
|
int Begin(void)
|
|
{
|
|
mCurrent = mHead;
|
|
return mUsedCount;
|
|
};
|
|
|
|
int GetUsedCount(void) const { return mUsedCount; };
|
|
int GetFreeCount(void) const { return mFreeCount; };
|
|
|
|
Type * GetNext(void)
|
|
{
|
|
if ( !mHead ) return 0; // there is no data to process.
|
|
|
|
Type *ret;
|
|
|
|
if ( !mCurrent )
|
|
{
|
|
ret = mHead;
|
|
}
|
|
else
|
|
{
|
|
ret = mCurrent;
|
|
}
|
|
|
|
if ( ret ) mCurrent = ret->GetNext();
|
|
|
|
|
|
return ret;
|
|
};
|
|
|
|
void Release(Type *t)
|
|
{
|
|
|
|
if ( t == mCurrent ) mCurrent = t->GetNext();
|
|
|
|
// first patch old linked list.. his previous now points to his next
|
|
Type *prev = t->GetPrevious();
|
|
|
|
if ( prev )
|
|
{
|
|
Type *next = t->GetNext();
|
|
prev->SetNext( next ); // my previous now points to my next
|
|
if ( next ) next->SetPrevious(prev);
|
|
// list is patched!
|
|
}
|
|
else
|
|
{
|
|
Type *next = t->GetNext();
|
|
mHead = next;
|
|
if ( mHead ) mHead->SetPrevious(0);
|
|
}
|
|
|
|
Type *temp = mFree; // old head of free list.
|
|
mFree = t; // new head of linked list.
|
|
t->SetPrevious(0);
|
|
t->SetNext(temp);
|
|
|
|
mUsedCount--;
|
|
mFreeCount++;
|
|
};
|
|
|
|
Type * GetFreeNoLink(void) // get free, but don't link it to the used list!!
|
|
{
|
|
// Free allocated items are always added to the head of the list
|
|
if ( !mFree ) return 0;
|
|
Type *ret = mFree;
|
|
mFree = ret->GetNext(); // new head of free list
|
|
mUsedCount++;
|
|
mFreeCount--;
|
|
ret->SetNext(0);
|
|
ret->SetPrevious(0);
|
|
return ret;
|
|
};
|
|
|
|
Type * GetFreeLink(void)
|
|
{
|
|
// Free allocated items are always added to the head of the list
|
|
if ( !mFree ) return 0;
|
|
Type *ret = mFree;
|
|
mFree = ret->GetNext(); // new head of free list
|
|
Type *temp = mHead; // current head of list
|
|
mHead = ret; // new head of list is this free one
|
|
if ( temp ) temp->SetPrevious(ret);
|
|
mHead->SetNext(temp);
|
|
mHead->SetPrevious(0);
|
|
mUsedCount++;
|
|
mFreeCount--;
|
|
return ret;
|
|
};
|
|
|
|
void AddAfter(Type *e,Type *item)
|
|
{
|
|
// Add 'item' after 'e'
|
|
if ( e )
|
|
{
|
|
Type *eprev = e->GetPrevious();
|
|
Type *enext = e->GetNext();
|
|
e->SetNext(item);
|
|
item->SetNext(enext);
|
|
item->SetPrevious(e);
|
|
if ( enext ) enext->SetPrevious(item);
|
|
}
|
|
else
|
|
{
|
|
mHead = item;
|
|
item->SetPrevious(0);
|
|
item->SetNext(0);
|
|
}
|
|
|
|
}
|
|
|
|
void AddBefore(Type *e,Type *item)
|
|
{
|
|
// Add 'item' before 'e'
|
|
Type *eprev = e->GetPrevious();
|
|
Type *enext = e->GetNext();
|
|
|
|
if ( !eprev )
|
|
mHead = item;
|
|
else
|
|
eprev->SetNext(item);
|
|
|
|
item->SetPrevious(eprev);
|
|
item->SetNext(e);
|
|
|
|
e->SetPrevious(item);
|
|
|
|
}
|
|
|
|
|
|
private:
|
|
int mMaxItems;
|
|
Type *mCurrent; // current iteration location.
|
|
Type *mData;
|
|
Type *mHead; // head of used list.
|
|
Type *mFree; // head of free list.
|
|
int mUsedCount;
|
|
int mFreeCount;
|
|
};
|