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

Macros

#define BDLMA_LOCAL_BUFFERED_VALUE_IS_ASSIGNABLE(DST, SRC)    std::is_assignable<DST, SRC>::value
 

Detailed Description

Outline

Purpose

Provide easy way to create an object with a local arena allocator.

Classes

See also
bdlma_localsequentialalallocator

Description

This component provides a mechanism, LocalBufferedObject, that contains a single instance of an allocator-aware object instantiated using an arena allocator that will allocate from "local" memory. This type is primarily used to simplify the creation of temporary objects utilizing a local memory buffer (typically on the stack) for efficiency, and is equivalent to creating a temporary object and supplying it a bdlma::LocalSequentialAllocator. There are three template parameters – the type of object contained, the size in bytes of the buffer in the local arena allocator, and a bool to indicate whether destruction of the contained object is to be disabled during emplace and destruction of the mechansim. If the buffer used by the local arena allocator is exhausted, subsequent allocations come from the allocator passed at construction, or the default allocator if no allocator was passed at construction. Note that calls to deallocate by the held object are ignored.

The container has 4 types of constructors:

  1. A constructor that takes an arbitary set of arguments, propagated to the object.
  2. A constructor like 1 above, but also passed an allocator.
  3. A constructor that takes a std::initializer_list, propagated to the object.
  4. A constructor like 3 above, but also passed an allocator.

t_DISABLE_DESTRUCTION Template Parameter:

If t_DISABLE_DESTRUCTOR is set to true, the LocalBufferedObject, upon destruction or emplace, will not destroy the contained object but will instead simply release any allocated memory. Eliding the contained objects destructor may improve efficiency, but is safe only if the contained object does not manage resources other than memory. I.e., it is unsafe to set t_DISABLE_DESTRUCTOR to true if the contained object manages resources other than memory (e.g., file handles, locks). By default t_DISABLE_DESTRUCTOR is false.

It is important that t_DISABLE_DESTRUCTION be set to false (the default) if any resources other than memory, such as file handles or mutexes, are managed by the held object.

emplace Manipulators:

The class has two emplace manipulators,

Usage

Example 1: Configuring an Object to Allocate From Stack Memory

Suppose we have an array of bsl::string_views containing names, with a large number of redundant entries, and we want to count how many unique names exist in the array. We write a function countUniqueNames which stores the names in an unordered set, and yields the size accessor as the total count of unique names.

The function will be called many times, and bsl::unordered_set does a large number of small memory allocations. These allocations would be faster if they came from a non-freeing allocator that gets its memory from a buffer on the stack.

We can use a LocalBufferedObject to create an unordered_set with an 8192-byte stack buffer from which it is to allocate memory.

size_t countUniqueNames(const bsl::string_view *rawNames,
size_t numRawNames)
{
8192> uset;
for (unsigned uu = 0; uu < numRawNames; ++uu) {
uset->insert(rawNames[uu]);
}
return uset->size();
}
Definition bdlma_localbufferedobject.h:261
Definition bslstl_stringview.h:441

Notice that this syntactic convenience equivalent to supplying a local LocalSequentialAllocator to the bsl::unordered_set.

Below we show the allocation behavior of this function as the number of items in the unordered_set increases. Note that when the memory in the 8192-byte stack buffer is exhausted, further memory comes from the default allocator:

'countUniqueNames':
Names: (raw: 25, unique: 23), used default allocator: 0
Names: (raw: 50, unique: 42), used default allocator: 0
Names: (raw: 100, unique: 70), used default allocator: 0
Names: (raw: 200, unique: 103), used default allocator: 0
Names: (raw: 400, unique: 130), used default allocator: 1
Names: (raw: 800, unique: 143), used default allocator: 1
Names: (raw: 1600, unique: 144), used default allocator: 1

Example 2: Eliding the Destructor

Because the only resource managed by the unordered_set is memory, we can improve the performance of the previous example using the template's boolean t_DISABLE_DESTRUCTOR parameter.

unordered_set allocates a lot of small nodes, and when the container is destroyed, unordered set's destructor traverses the whole data structure, visting every node and calling bslma::Allocator::deallocate on each one, which is a non-inline virtual function call eventually handled by the sequential allocator's deallocate function, which does nothing.

If we set the 3rd template parameter of LocalBufferedObject, which is t_DISABLE_DESTRUCTION of type bool, to the non-default value of true, the LocalBufferedObject will not call the destructor of the held unordered_set. This isn't a problem because unordered set manages no resource other than memory, and all the memory it uses is managed by the local sequential allocator contained in the local buffered object.

size_t countUniqueNamesFaster(const bsl::string_view *rawNames,
size_t numRawNames)
{
8192,
true> uset;
for (unsigned uu = 0; uu < numRawNames; ++uu) {
uset->insert(rawNames[uu]);
}
return uset->size();
}

And we see the calculations are exactly the same:

'countUniqueNamesFaster': destructor disabled:
Names: (raw: 25, unique: 23), used default allocator: 0
Names: (raw: 50, unique: 42), used default allocator: 0
Names: (raw: 100, unique: 70), used default allocator: 0
Names: (raw: 200, unique: 103), used default allocator: 0
Names: (raw: 400, unique: 130), used default allocator: 1
Names: (raw: 800, unique: 143), used default allocator: 1
Names: (raw: 1600, unique: 144), used default allocator: 1

Macro Definition Documentation

◆ BDLMA_LOCAL_BUFFERED_VALUE_IS_ASSIGNABLE

#define BDLMA_LOCAL_BUFFERED_VALUE_IS_ASSIGNABLE (   DST,
  SRC 
)     std::is_assignable<DST, SRC>::value