|
|
#ifndef _BUCKET_HPP_
#define _BUCKET_HPP_
// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/ /* */ /* The standard layout. */ /* */ /* The standard layout for 'hpp' files for this code is as */ /* follows: */ /* */ /* 1. Include files. */ /* 2. Constants exported from the class. */ /* 3. Data structures exported from the class. */ /* 4. Forward references to other data structures. */ /* 5. Class specifications (including inline functions). */ /* 6. Additional large inline functions. */ /* */ /* Any portion that is not required is simply omitted. */ /* */ /********************************************************************/
#include "Global.hpp"
#include "Connections.hpp"
#include "Page.hpp"
/********************************************************************/ /* */ /* Class forward references. */ /* */ /* We need to refer to the following classes before they are */ /* fully specified so here we list them as forward references. */ /* */ /********************************************************************/
class CACHE; class HEAP;
/********************************************************************/ /* */ /* A collection of pages. */ /* */ /* A bucket is a collection of pages capable of allocating */ /* fixed sized memory elements. The pages are allocated from */ /* from larger buckets and are stored in a linked list in */ /* order of ascending of page addresses. */ /* */ /********************************************************************/
class BUCKET : public CONNECTIONS { //
// Private type definitions.
//
// All allocations are registered in bit vectors.
// Here we have some prototypes for seriously
// optimized functions to do address to bit
// vector computations.
//
typedef VOID *(BUCKET::*COMPUTE_ADDRESS) ( CHAR *Address, SBIT32 Offset );
typedef SBIT32 (BUCKET::*COMPUTE_OFFSET) ( SBIT32 Displacement, BOOLEAN *Found );
//
// Private data.
//
// A bucket owns all the memory of a given size
// and manages it. Above it is a cache to
// protect it from huge number of calls and
// below it are the connections to various
// other classes. The 'AllocationSize' is the
// buckets allocation size. The 'ChunkSize' is
// chunking size which is typically half way
// between the 'AllocationSize' and the 'PageSize'.
// The 'PageSize' is the size of the bucket
// where this bucket gets its space.
//
//
SBIT32 AllocationSize; SBIT32 ChunkSize; SBIT32 PageSize;
//
// It is the job of the bucket to keep track of
// all the information relating to allocations
// of a given 'AllocationSize'. The 'ActivePages'
// keeps track of the number of available pages
// in the 'BucketList'. The 'BucketList' is a
// linked list of pages that have available space.
// The 'CurrentPage' contains the highest address
// of the first page in the 'BucketList'.
//
SBIT32 ActivePages; LIST BucketList; VOID *CurrentPage;
//
// A bucket needs to be able to quickly convert
// bit vector offsets to addresses (and vice versa).
// The 'AllocationShift' is set when the
// 'AllocationSize' is a power of two to avoid
// any divides. The 'ChunkShift' is set when the
// 'ChunckSize' is a power of two to avoid some
// divides. The 'ComputeAddressFunction' and
// 'ComputeOffsetFunction' point to optimized
// functions to do conversions that are selected
// by the constructor.
//
SBIT32 AllocationShift; SBIT32 ChunkShift; COMPUTE_ADDRESS ComputeAddressFunction; COMPUTE_OFFSET ComputeOffsetFunction;
//
// A bucket typically contains a collection of
// pages. As all pages are the same data that
// should really be stored in page descriptions
// is instead stored in the bucket to save space.
// The 'NumberOfElements' contains the number of
// elements in each pages bit vector. The
// 'SizeOfChunks' contains the pre-computed chunk
// size. The 'SizeOfElements' contains the number
// of words in the pages bit vector. The 'SizeKey'
// contains an index which selects the size of the
// bit vector when a new page is created.
//
SBIT16 NumberOfElements; SBIT16 SizeOfChunks; SBIT16 SizeOfElements; SBIT16 SizeKey;
public: //
// Public functions.
//
// The functionality provided by this class pretty
// much matches the external API. Nonetheless, these
// APIs are protected from excessive calls by a fast
// cache that is derived from this class.
//
BUCKET ( SBIT32 NewAllocationSize, SBIT32 NewChunkSize, SBIT32 NewPageSize );
BOOLEAN Delete( VOID *Address,PAGE *Page,SBIT32 Version );
VOID DeleteFromBucketList( PAGE *Page );
VOID InsertInBucketList( PAGE *Page );
BOOLEAN MultipleDelete ( ADDRESS_AND_PAGE *Array, SBIT32 *Deleted, SBIT32 Size );
BOOLEAN MultipleNew ( SBIT32 *Actual, VOID *Array[], SBIT32 Requested );
VOID *New( BOOLEAN SubDivided,SBIT32 NewSize = NoSize );
VOID ReleaseSpace( SBIT32 MaxActivePages );
VOID UpdateBucket ( FIND *NewFind, HEAP *NewHeap, NEW_PAGE *NewPages, CACHE *NewParentCache );
~BUCKET( VOID );
//
// Public inline functions.
//
// It saves a significant amount of space by putting
// common information in the bucket instead of a
// separate copy in each page description. Nonetheless,
// it means that both classes are very much dependent
// upon each other.
//
INLINE VOID *ComputeAddress( CHAR *Address,SBIT32 Offset ) { return (this ->* ComputeAddressFunction)( Address,Offset ); }
INLINE SBIT32 ComputeOffset( SBIT32 Displacement,BOOLEAN *Found ) { return (this ->* ComputeOffsetFunction)( Displacement,Found ); }
INLINE SBIT32 GetAllocationSize( VOID ) { return AllocationSize; }
INLINE SBIT32 GetChunkSize( VOID ) { return ChunkSize; }
VOID *GetCurrentPage( VOID ) { return CurrentPage; }
INLINE SBIT16 GetNumberOfElements( VOID ) { return NumberOfElements; }
INLINE SBIT32 GetPageSize( VOID ) { return PageSize; }
INLINE SBIT16 GetSizeOfChunks( VOID ) { return SizeOfChunks; }
INLINE SBIT16 GetSizeOfElements( VOID ) { return SizeOfElements; }
INLINE SBIT16 GetSizeKey( VOID ) { return SizeKey; }
private: //
// Private functions.
//
// When we need to convert an address to a bit
// offset (or vice versa) we use one of the following
// functions.
//
VOID *ComputeAddressBestCase( CHAR *Address,SBIT32 Offset ); VOID *ComputeAddressGoodCase( CHAR *Address,SBIT32 Offset ); VOID *ComputeAddressPoorCase( CHAR *Address,SBIT32 Offset ); VOID *ComputeAddressWorstCase( CHAR *Address,SBIT32 Offset );
SBIT32 ComputeOffsetBestCase( SBIT32 Displacement,BOOLEAN *Found ); SBIT32 ComputeOffsetGoodCase( SBIT32 Displacement,BOOLEAN *Found ); SBIT32 ComputeOffsetPoorCase( SBIT32 Displacement,BOOLEAN *Found ); SBIT32 ComputeOffsetWorstCase( SBIT32 Displacement,BOOLEAN *Found );
//
// Disabled operations.
//
// All copy constructors and class assignment
// operations are disabled.
//
BUCKET( CONST BUCKET & Copy );
VOID operator=( CONST BUCKET & Copy ); }; #endif
|