mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 05:54:28 +02:00
Optimize merge and sort with the utility unused_storage
This commit is contained in:
@@ -121,6 +121,7 @@ namespace boost {
|
|||||||
namespace container {
|
namespace container {
|
||||||
namespace dtl {
|
namespace dtl {
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Helper functions to merge elements
|
// Helper functions to merge elements
|
||||||
@@ -138,14 +139,19 @@ template<class SequenceContainer, class Compare>
|
|||||||
inline void flat_tree_container_inplace_merge //is_contiguous_container == true
|
inline void flat_tree_container_inplace_merge //is_contiguous_container == true
|
||||||
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_)
|
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_)
|
||||||
{
|
{
|
||||||
typedef typename SequenceContainer::value_type value_type;
|
typedef typename SequenceContainer::value_type value_type;
|
||||||
|
typedef typename SequenceContainer::size_type size_type;
|
||||||
|
|
||||||
value_type *const braw = boost::movelib::to_raw_pointer(dest.data());
|
value_type *const braw = boost::movelib::to_raw_pointer(dest.data());
|
||||||
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
||||||
//Don't use iterator_to_raw_pointer for end as debug iterators can assert when
|
//Don't use iterator_to_raw_pointer for end as debug iterators can assert when
|
||||||
//"operator ->" is used with the end iterator
|
//"operator ->" is used with the end iterator
|
||||||
value_type *const eraw = braw + dest.size();
|
value_type *const eraw = braw + dest.size();
|
||||||
|
size_type dest_unused_storage_size = 0;
|
||||||
|
value_type *const dest_unused_storage_addr =
|
||||||
|
unused_storage<SequenceContainer>::get(dest, dest_unused_storage_size);
|
||||||
boost::movelib::adaptive_merge
|
boost::movelib::adaptive_merge
|
||||||
(braw, iraw, eraw, comp, eraw, back_free_capacity<SequenceContainer>::get(dest));
|
(braw, iraw, eraw, comp, dest_unused_storage_addr, dest_unused_storage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Compare>
|
template<class SequenceContainer, class Compare>
|
||||||
@@ -164,15 +170,19 @@ template<class SequenceContainer, class Compare>
|
|||||||
inline void flat_tree_container_inplace_sort_ending //is_contiguous_container == true
|
inline void flat_tree_container_inplace_sort_ending //is_contiguous_container == true
|
||||||
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::true_)
|
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::true_)
|
||||||
{
|
{
|
||||||
typedef typename SequenceContainer::value_type value_type;
|
typedef typename SequenceContainer::value_type value_type;
|
||||||
|
typedef typename SequenceContainer::size_type size_type;
|
||||||
|
|
||||||
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
|
||||||
//Don't use iterator_to_raw_pointer for end as debug iterators can assert when
|
//Don't use iterator_to_raw_pointer for end as debug iterators can assert when
|
||||||
//"operator ->" is used with the end iterator
|
//"operator ->" is used with the end iterator
|
||||||
value_type* const eraw = boost::movelib::to_raw_pointer(dest.data()) + dest.size();
|
value_type* const eraw = boost::movelib::to_raw_pointer(dest.data()) + dest.size();
|
||||||
|
|
||||||
|
size_type dest_unused_storage_size;
|
||||||
|
value_type* const dest_unused_storage_addr =
|
||||||
|
unused_storage<SequenceContainer>::get(dest, dest_unused_storage_size);
|
||||||
boost::movelib::adaptive_sort
|
boost::movelib::adaptive_sort
|
||||||
(iraw, eraw, comp, eraw, back_free_capacity<SequenceContainer>::get(dest));
|
(iraw, eraw, comp, dest_unused_storage_addr, dest_unused_storage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Compare>
|
template<class SequenceContainer, class Compare>
|
||||||
@@ -320,23 +330,24 @@ template<class SequenceContainer, class Compare>
|
|||||||
void flat_tree_sort_contiguous_to_adopt // is_contiguous_container == true
|
void flat_tree_sort_contiguous_to_adopt // is_contiguous_container == true
|
||||||
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp)
|
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp)
|
||||||
{
|
{
|
||||||
if(tseq.capacity() >= (seq.capacity() - seq.size())) {
|
typedef typename SequenceContainer::value_type value_type;
|
||||||
tseq.clear();
|
typedef typename SequenceContainer::size_type size_type;
|
||||||
boost::movelib::adaptive_sort
|
|
||||||
(boost::movelib::iterator_to_raw_pointer(seq.begin())
|
size_type tseq_unused_storage_size, seq_unused_storage_size;
|
||||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
value_type* const tseq_unused_storage_addr =
|
||||||
, comp
|
unused_storage<SequenceContainer>::get(tseq, tseq_unused_storage_size);
|
||||||
, boost::movelib::iterator_to_raw_pointer(tseq.begin())
|
value_type* const seq_unused_storage_addr =
|
||||||
, tseq.capacity());
|
unused_storage<SequenceContainer>::get(seq, seq_unused_storage_size);
|
||||||
}
|
|
||||||
else{
|
tseq.clear();
|
||||||
boost::movelib::adaptive_sort
|
const bool use_tseq_storage = tseq_unused_storage_size > seq_unused_storage_size;
|
||||||
(boost::movelib::iterator_to_raw_pointer(seq.begin())
|
|
||||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
boost::movelib::adaptive_sort
|
||||||
, comp
|
( boost::movelib::iterator_to_raw_pointer(seq.begin())
|
||||||
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
, boost::movelib::iterator_to_raw_pointer(seq.end())
|
||||||
, seq.capacity() - seq.size());
|
, comp
|
||||||
}
|
, use_tseq_storage ? tseq_unused_storage_addr : seq_unused_storage_addr
|
||||||
|
, use_tseq_storage ? tseq_unused_storage_size : seq_unused_storage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SequenceContainer, class Compare>
|
template<class SequenceContainer, class Compare>
|
||||||
|
@@ -31,9 +31,9 @@
|
|||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
||||||
|
|
||||||
//back_free_capacity
|
//free_storage
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME back_free_capacity
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME unused_storage
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace back_free_capacity_detail {
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace unused_storage_detail {
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
||||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
||||||
@@ -60,19 +60,23 @@ struct is_contiguous_container
|
|||||||
|
|
||||||
|
|
||||||
template < class Container
|
template < class Container
|
||||||
, bool = boost::container::back_free_capacity_detail::
|
, bool = boost::container::unused_storage_detail::
|
||||||
has_member_function_callable_with_back_free_capacity<const Container>::value>
|
has_member_function_callable_with_unused_storage<const Container>::value>
|
||||||
struct back_free_capacity
|
struct unused_storage
|
||||||
{
|
{
|
||||||
static typename Container::size_type get(const Container &c)
|
static typename Container::value_type* get(Container &c, typename Container::size_type &s)
|
||||||
{ return c.back_free_capacity(); }
|
{ return c.unused_storage(s); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template < class Container>
|
template < class Container>
|
||||||
struct back_free_capacity<Container, false>
|
struct unused_storage<Container, false>
|
||||||
{
|
{
|
||||||
static typename Container::size_type get(const Container &c)
|
static typename Container::value_type* get(Container&, typename Container::size_type &s)
|
||||||
{ return c.capacity() - c.size(); }
|
{
|
||||||
|
s = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace dtl {
|
} //namespace dtl {
|
||||||
|
Reference in New Issue
Block a user