* Improved vector's insertion performance.

*  Changed again experimental multiallocation interface for better performance (still experimental).
*  Added no exception support for those willing to disable exceptions in their compilers.
*  Fixed GCC -Wshadow warnings.
*  Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.


[SVN r81518]
This commit is contained in:
Ion Gaztañaga
2012-11-24 21:08:18 +00:00
parent a75d72d03c
commit bc5c91bb79
28 changed files with 2449 additions and 1892 deletions
@@ -26,10 +26,12 @@
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/assert.hpp>
#include <cstddef>
#include <functional> //std::unary_function
namespace boost {
namespace container {
namespace container_detail {
@@ -85,19 +87,19 @@ class private_node_pool_impl
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
void *allocate_node()
{ return priv_alloc_node(); }
{ return this->priv_alloc_node(); }
//!Deallocates an array pointed by ptr. Never throws
void deallocate_node(void *ptr)
{ priv_dealloc_node(ptr); }
{ this->priv_dealloc_node(ptr); }
//!Allocates a singly linked list of n nodes ending in null pointer.
multiallocation_chain allocate_nodes(const size_type n)
void allocate_nodes(const size_type n, multiallocation_chain &chain)
{
//Preallocate all needed blocks to fulfill the request
size_type cur_nodes = m_freelist.size();
if(cur_nodes < n){
priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
this->priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
}
//We just iterate the needed nodes to get the last we'll erase
@@ -118,20 +120,18 @@ class private_node_pool_impl
//Now take the last erased node and just splice it in the end
//of the intrusive list that will be traversed by the multialloc iterator.
multiallocation_chain chain;
chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
m_allocated += n;
return boost::move(chain);
}
void deallocate_nodes(multiallocation_chain chain)
void deallocate_nodes(multiallocation_chain &chain)
{
typedef typename multiallocation_chain::iterator iterator;
iterator it(chain.begin()), itend(chain.end());
while(it != itend){
void *pElem = &*it;
++it;
priv_dealloc_node(pElem);
this->priv_dealloc_node(pElem);
}
}
@@ -275,7 +275,7 @@ class private_node_pool_impl
{
//If there are no free nodes we allocate a new block
if (m_freelist.empty())
priv_alloc_block();
this->priv_alloc_block(1);
//We take the first free node
node_t *n = (node_t*)&m_freelist.front();
m_freelist.pop_front();
@@ -295,14 +295,13 @@ class private_node_pool_impl
}
//!Allocates several blocks of nodes. Can throw
void priv_alloc_block(size_type num_blocks = 1)
void priv_alloc_block(size_type num_blocks)
{
if(!num_blocks)
return;
BOOST_ASSERT(num_blocks > 0);
size_type blocksize =
get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
try{
BOOST_TRY{
for(size_type i = 0; i != num_blocks; ++i){
//We allocate a new NodeBlock and put it as first
//element in the free Node list
@@ -313,15 +312,16 @@ class private_node_pool_impl
//We initialize all Nodes in Node Block to insert
//them in the free Node list
for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
for(size_type j = 0; j < m_nodes_per_block; ++j, pNode += m_real_node_size){
m_freelist.push_front(*new (pNode) node_t);
}
}
}
catch(...){
BOOST_CATCH(...){
//to-do: if possible, an efficient way to deallocate allocated blocks
throw;
BOOST_RETHROW
}
BOOST_CATCH_END
}
//!Deprecated, use deallocate_free_blocks