#if !defined(_INLINE)
static char cvsid[] = "@(#)$Id$";
static char debugFileId[] = __FILE__;
#endif
#include "FixedSizeAllocator.hpp"
#include "String.hpp"
#include "Debug.hpp"
FixedSizeAllocator::FixedSizeAllocator( const Index aDefaultSize,
const Index aSegmentSize,
const char *aName ) :
defaultSize( aDefaultSize ),
segmentSize( aSegmentSize ),
name( aName )
{
sure_( defaultSize > 0 );
sure_( segmentSize > 0 );
headOfFreeList = NIL;
segmentChain = ( Segment * ) NIL;
#if defined( PROFILE_MEM_ALLOC )
totalAllocated = 0;
actualAllocated = 0;
maxAllocated = 0;
averageAllocated = 0;
totalSegments = 0;
actualSegments = 0;
maxSegments = 0;
averageSegments = 0;
addToDump( this );
#endif
}
FixedSizeAllocator::~FixedSizeAllocator()
{
Segment *current;
current = segmentChain;
while( current != ( Segment * ) NIL )
{
current = current -> nextInChain;
delete []current;
}
}
void *FixedSizeAllocator::allocate( Index aNumberOfBytes )
{
sure_( aNumberOfBytes == defaultSize );
#if defined( PROFILE_MEM_ALLOC )
Index total;
total = ++totalAllocated;
++actualAllocated;
if( actualAllocated > maxAllocated )
{
maxAllocated = actualAllocated;
}
averageAllocated = ( ( averageAllocated * ( total - 1 ) ) + actualAllocated ) / total;
averageSegments = ( ( averageSegments * ( total - 1 ) ) + actualSegments ) / total;
#endif
if( headOfFreeList != NIL )
{
char *result;
result = headOfFreeList;
headOfFreeList = * ( char ** ) headOfFreeList;
return result;
}
char *shuttle;
Segment *newSegment;
#if defined( PROFILE_MEM_ALLOC )
++totalSegments;
++actualSegments;
if( actualSegments > maxSegments )
{
maxSegments = actualSegments;
}
#endif
newSegment = new Segment();
newSegment -> nextInChain = segmentChain;
segmentChain = newSegment;
newSegment -> area = new char[ segmentSize * defaultSize ];
shuttle = ( newSegment -> area ) + defaultSize;
for( Index i = 1 ; i < ( segmentSize - 1 ) ; ++i )
{
*( ( char ** ) shuttle ) = shuttle + defaultSize;
shuttle += defaultSize;
}
*( char ** )shuttle = headOfFreeList;
headOfFreeList = ( newSegment -> area ) + defaultSize;
return ( void * ) ( newSegment -> area );
}
void FixedSizeAllocator::deallocate( void *anAddress )
{
if( anAddress == NULL )
{
return;
}
( *( char ** ) anAddress )= headOfFreeList;
headOfFreeList = ( char * ) anAddress;
#if defined( PROFILE_MEM_ALLOC )
--actualAllocated;
#endif
}
Top *FixedSizeAllocator::clone() const
{
return ( Top * ) new FixedSizeAllocator( defaultSize, segmentSize, name );
}
String FixedSizeAllocator::toString() const
{
return Object::toString() + " defaultSize: " + String( defaultSize ) +
" segmentSize: " + String( segmentSize ) + " cells"
#if defined( PROFILE_MEM_ALLOC )
+
" name: " + String( name, false ) +
" total calls: " + String( totalAllocated ) +
" actually allocated: " + String( actualAllocated ) +
" maximum allocated: " + String( maxAllocated ) +
" average allocated: ( " + String( ( Index ) ( averageAllocated * 1000 ) ) +
" / 1000 )" +
" total segments: " + String( totalSegments ) +
" actual segments: " + String( actualSegments ) +
" average segments: " + String( ( Index ) ( averageSegments * 1000 ) ) +
" / 1000 )"
#endif
;
}
String FixedSizeAllocator::getClassName() const
{
return "FixedSizeAllocator";
}
#if defined(_INLINE)
#include "../src/Debug.ipp"
#endif