Provide allocation and management of a sequence of memory blocks.
More...
Namespaces |
namespace | bslma |
Detailed Description
- Outline
-
-
- Purpose:
- Provide allocation and management of a sequence of memory blocks.
- Deprecated:
- Use bdlma_infrequentdeleteblocklist instead.
-
- Classes:
-
- See also:
- Component bdlma_infrequentdeleteblocklist
-
- Description:
- This component implements a memory manager that allocates and manages a sequence of memory blocks, each potentially of a different size as specified in the
allocate
method's invocation. The bslma::InfrequentDeleteBlockList
object's release
method deallocates the entire sequence of memory blocks, as does its destructor.
- This component does not allow individual items to be deallocated.
-
- Usage:
- The
bslma::InfrequentDeleteBlockList
object is commonly used to supply memory to more elaborate memory managers that distribute parts of a memory block supplied by the bslma::InfrequentDeleteBlockList
object. The my_StrPool
memory pool manager shown below requests relatively large blocks of memory from its bslma::InfrequentDeleteBlockList
member object and distributes memory chunks of varying sizes from each block on demand:
class my_StrPool {
int d_blockSize;
char *d_block_p;
int d_cursor;
bslma::InfrequentDeleteBlockList d_blockList;
private:
void *allocateBlock(int numBytes);
private:
my_StrPool(const my_StrPool&);
my_StrPool& operator=(const my_StrPool&);
public:
my_StrPool(bslma::Allocator *basicAllocator = 0);
~my_StrPool();
void *allocate(int numBytes);
void release();
};
inline
void *my_StrPool::allocate(int numBytes)
{
if (numBytes <= 0) {
return 0;
}
if (d_block_p && numBytes + d_cursor <= d_blockSize) {
char *p = d_block_p + d_cursor;
d_cursor += numBytes;
return p;
}
else {
return allocateBlock(numBytes);
}
}
inline
void my_StrPool::release()
{
d_blockList.release();
d_block_p = 0;
}
enum {
INITIAL_SIZE = 128,
GROW_FACTOR = 2,
THRESHOLD = 128
};
void *my_StrPool::allocateBlock(int numBytes)
{
ASSERT(0 < numBytes);
if (THRESHOLD < numBytes) {
return (char *) d_blockList.allocate(numBytes);
}
else {
if (d_block_p) {
d_blockSize *= GROW_FACTOR;
}
d_block_p = (char *) d_blockList.allocate(d_blockSize);
d_cursor = numBytes;
return d_block_p;
}
}
my_StrPool::my_StrPool(bslma::Allocator *basicAllocator)
: d_blockSize(INITIAL_SIZE)
, d_block_p(0)
, d_blockList(basicAllocator)
{
}
my_StrPool::~my_StrPool()
{
assert(INITIAL_SIZE <= d_blockSize);
assert(d_block_p || 0 <= d_cursor && d_cursor <= d_blockSize);
}
In the code above, the my_StrPool
memory manager allocates from its bslma::InfrequentDeleteBlockList
member object an initial memory block of size INITIAL_SIZE
. This size is multiplied by GROW_FACTOR
each time a deplete memory block is replaced by a newly allocated block. The allocate
method distributes memory from the current memory block piecemeal, except when the requested size: 1) is not available in the current block and 2) exceeds the THRESHOLD_SIZE
, in which case a separate memory block is allocated and returned. When the my_StrPool
memory manager is destroyed, its bslma::InfrequentDeleteBlockList
member object is also destroyed, which in turn automatically deallocates all of its managed memory blocks.