BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_infrequentdeleteblocklist

Detailed Description

Outline

Purpose

Provide allocation and management of infrequently deleted blocks.

Classes

See also
bdlma_blocklist

Description

This component implements a low-level memory manager, bdlma::InfrequentDeleteBlockList, that allocates and manages a sequence of memory blocks, each of a potentially different size as specified during the allocate method's invocation. The release method of a bdlma::InfrequentDeleteBlockList object deallocates the entire sequence of outstanding memory blocks, as does its destructor. Note that, in contrast to bdlma::BlockList, the bdlma::InfrequentDeleteBlockList class does not support the deallocation of individual items. In particular, although bdlma::InfrequentDeleteBlockList has a deallocate method, that method has no effect.

Usage

This section illustrates intended use of this component.

Example 1: Creating a Memory Pools for Strings

A bdlma::InfrequentDeleteBlockList object is commonly used to supply memory to more elaborate memory managers that distribute parts of each (larger) allocated memory block supplied by the bdlma::InfrequentDeleteBlockList object. The my_StrPool memory pool manager shown below requests relatively large blocks of memory from its bdlma::InfrequentDeleteBlockList member object and distributes memory chunks of varying sizes from each block on demand:

// my_strpool.h
class my_StrPool {
// DATA
char *d_block_p; // current memory block
bsls::Types::size_type d_blockSize; // size of current memory block
bsls::Types::IntPtr d_cursor; // offset to next available byte
// in block
d_blockList; // supplies managed memory blocks
private:
// PRIVATE MANIPULATORS
void *allocateBlock(bsls::Types::size_type numBytes);
// Request a memory block of at least the specified 'numBytes' size
// and allocate the initial 'numBytes' from this block. Return the
// address of the allocated memory. The behavior is undefined
// unless '0 < numBytes'.
private:
// NOT IMPLEMENTED
my_StrPool(const my_StrPool&);
my_StrPool& operator=(const my_StrPool&);
public:
// CREATORS
explicit
my_StrPool(bslma::Allocator *basicAllocator = 0);
// Create a string pool. Optionally specify a 'basicAllocator'
// used to supply memory. If 'basicAllocator' is 0, the currently
// installed default allocator is used.
~my_StrPool();
// Destroy this object and release all associated memory.
// MANIPULATORS
void *allocate(bsls::Types::size_type size);
// Return the address of a contiguous block of memory of the
// specified 'size' (in bytes). If 'size' is 0, no memory is
// allocated and 0 is returned.
void release();
// Release all memory currently allocated through this object.
};
// MANIPULATORS
inline
void my_StrPool::release()
{
d_blockList.release();
d_block_p = 0;
}
// ...
// my_strpool.cpp
enum {
k_INITIAL_SIZE = 128, // initial block size
k_GROWTH_FACTOR = 2, // multiplicative factor by which to grow block
k_THRESHOLD = 128 // size beyond which an individual block may be
// allocated if it doesn't fit in current block
};
// PRIVATE MANIPULATORS
void *my_StrPool::allocateBlock(bsls::Types::size_type numBytes)
{
assert(0 < numBytes);
if (k_THRESHOLD < numBytes) {
// Allocate separate block if above threshold.
return reinterpret_cast<char *>(
d_blockList.allocate(numBytes)); // RETURN
}
if (d_block_p) {
// Do not increase block size if no current block.
d_blockSize *= k_GROWTH_FACTOR;
}
d_block_p = reinterpret_cast<char*>(d_blockList.allocate(d_blockSize));
d_cursor = numBytes;
return d_block_p;
}
// CREATORS
my_StrPool::my_StrPool(bslma::Allocator *basicAllocator)
: d_block_p(0)
, d_blockSize(k_INITIAL_SIZE)
, d_cursor(0)
, d_blockList(basicAllocator) // the blocklist knows about 'bslma_default'
{
}
my_StrPool::~my_StrPool()
{
assert(k_INITIAL_SIZE <= d_blockSize);
assert(!d_block_p || (0 <= d_cursor && d_cursor <=
static_cast<bsls::Types::IntPtr>(d_blockSize)));
}
// MANIPULATORS
void *my_StrPool::allocate(bsls::Types::size_type size)
{
if (0 == size) {
return 0; // RETURN
}
if (d_block_p && size + d_cursor <= d_blockSize) {
char *p = d_block_p + d_cursor;
d_cursor += size;
return p; // RETURN
}
else {
return allocateBlock(size); // RETURN
}
}
Definition bdlma_infrequentdeleteblocklist.h:241
Definition bslma_allocator.h:457
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
std::size_t size_type
Definition bsls_types.h:124
std::ptrdiff_t IntPtr
Definition bsls_types.h:130

In the code shown above, the my_StrPool memory manager allocates from its bdlma::InfrequentDeleteBlockList member object an initial memory block of size k_INITIAL_SIZE. This size is multiplied by k_GROWTH_FACTOR each time a depleted 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, or (2) exceeds the k_THRESHOLD, in which case a separate memory block is allocated and returned. When the my_StrPool memory manager is destroyed, its bdlma::InfrequentDeleteBlockList member object is also destroyed, which in turn automatically deallocates all of its managed memory blocks.