forked from boostorg/move
Fixed adaptive_sort/merge bugs for stability.
This commit is contained in:
1 parent
0c492d7548
commit
de55af3cbb
15 files changed
+1746
-1139
No files matched your search
@@ -0,0 +1,283 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/move for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
|
||||
#define BOOST_MOVE_ADAPTIVE_SORT_STATS
|
||||
|
||||
#include "order_type.hpp"
|
||||
|
||||
#include <iostream> //std::cout
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/move/algo/detail/adaptive_sort_merge.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <boost/move/make_unique.hpp>
|
||||
|
||||
#include <boost/move/detail/type_traits.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
const std::size_t BlockSize = 7u;
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning (disable : 4267)
|
||||
#endif
|
||||
|
||||
|
||||
const std::size_t left_merge = 0;
|
||||
const std::size_t buf_merge = 1;
|
||||
const std::size_t unbuf_merge= 2;
|
||||
const std::size_t max_merge = 3;
|
||||
|
||||
template<class Op>
|
||||
void alternating_test(
|
||||
const std::size_t NumBlocksA,
|
||||
const std::size_t NumBlocksB,
|
||||
const std::size_t ExtraA,
|
||||
const std::size_t ExtraB,
|
||||
Op op)
|
||||
{
|
||||
using namespace boost::movelib::detail_adaptive;
|
||||
|
||||
|
||||
const std::size_t DataSize = ExtraA + NumBlocksA*BlockSize + NumBlocksB*BlockSize + ExtraB;
|
||||
const std::size_t KeySize = NumBlocksA + NumBlocksB + 1;
|
||||
const std::size_t HdrSize = BlockSize + KeySize;
|
||||
const std::size_t ArraySize = HdrSize + DataSize;
|
||||
|
||||
boost::movelib::unique_ptr<order_move_type[]> testarray(boost::movelib::make_unique<order_move_type[]>(ArraySize));
|
||||
|
||||
|
||||
for(std::size_t szt_merge = 0; szt_merge != max_merge; ++szt_merge){
|
||||
//Order keys
|
||||
for (std::size_t szt_i = 0u; szt_i != KeySize; ++szt_i) {
|
||||
testarray[szt_i].key = szt_i;
|
||||
testarray[szt_i].val = std::size_t(-1);
|
||||
}
|
||||
|
||||
//Order buffer
|
||||
for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i) {
|
||||
testarray[KeySize+szt_i].key = std::size_t(-1);
|
||||
testarray[KeySize+szt_i].val = szt_i;
|
||||
}
|
||||
|
||||
//Block A
|
||||
std::size_t szt_k = 0;
|
||||
for (std::size_t szt_i = 0u; szt_i != ExtraA; ++szt_i) {
|
||||
testarray[HdrSize+szt_k].key = (szt_k/2)*2;
|
||||
testarray[HdrSize+szt_k].val = szt_k & 1;
|
||||
++szt_k;
|
||||
}
|
||||
|
||||
for (std::size_t szt_b = 0u; szt_b != NumBlocksA; ++szt_b)
|
||||
for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i) {
|
||||
testarray[HdrSize+szt_k].key = (szt_k/2)*2;
|
||||
testarray[HdrSize+szt_k].val = szt_k & 1;
|
||||
++szt_k;
|
||||
}
|
||||
|
||||
//Block B
|
||||
std::size_t szt_l = 0;
|
||||
for (std::size_t szt_b = 0u, szt_t = 0; szt_b != NumBlocksB; ++szt_b)
|
||||
for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i, ++szt_t) {
|
||||
testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
|
||||
testarray[HdrSize+szt_k].val = szt_l & 1;
|
||||
++szt_k;
|
||||
++szt_l;
|
||||
}
|
||||
|
||||
for (std::size_t szt_i = 0u; szt_i != ExtraB; ++szt_i) {
|
||||
testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
|
||||
testarray[HdrSize+szt_k].val = szt_l & 1;
|
||||
++szt_k;
|
||||
++szt_l;
|
||||
}
|
||||
|
||||
if(szt_merge == left_merge){
|
||||
//Merge Left
|
||||
op_merge_blocks_left
|
||||
( testarray.get(), order_type_less()
|
||||
, testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
|
||||
, order_type_less(), op );
|
||||
BOOST_TEST( is_order_type_ordered(testarray.get()+KeySize, DataSize) );
|
||||
BOOST_TEST( is_key(testarray.get(), KeySize) );
|
||||
BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
|
||||
|| is_buffer(testarray.get()+ KeySize+DataSize, BlockSize) ));
|
||||
}
|
||||
else if(szt_merge == buf_merge){
|
||||
//Merge with buf
|
||||
op_merge_blocks_with_buf
|
||||
( testarray.get(), order_type_less()
|
||||
, testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
|
||||
, order_type_less(), op, testarray.get()+KeySize );
|
||||
BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
|
||||
BOOST_TEST( is_key(testarray.get(), KeySize) );
|
||||
BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
|
||||
|| is_buffer(testarray.get()+ KeySize, BlockSize) ));
|
||||
}
|
||||
else if(szt_merge == unbuf_merge){
|
||||
//Merge Left
|
||||
merge_blocks_bufferless
|
||||
( testarray.get(), order_type_less()
|
||||
, testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
|
||||
, order_type_less());
|
||||
BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
|
||||
BOOST_TEST( is_key(testarray.get(), KeySize) );
|
||||
BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
|
||||
|| is_buffer(testarray.get()+ KeySize, BlockSize) ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = ExtraA;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = 0u;
|
||||
const std::size_t ExtraB = BlockSize/2;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 6u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = ExtraA;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 6u;
|
||||
const std::size_t NumBlocksB = 3u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 5u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = ExtraA;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 3u;
|
||||
const std::size_t NumBlocksB = 5u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = BlockSize/2;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
//
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 1u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 1u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 1u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 1u;
|
||||
const std::size_t ExtraA = BlockSize/2;
|
||||
const std::size_t ExtraB = 0;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 1u;
|
||||
const std::size_t NumBlocksB = 0u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = BlockSize/2;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
{
|
||||
const std::size_t NumBlocksA = 0u;
|
||||
const std::size_t NumBlocksB = 1u;
|
||||
const std::size_t ExtraA = 0;
|
||||
const std::size_t ExtraB = BlockSize/2;
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
|
||||
alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
|
||||
}
|
||||
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
Reference in new issue
Block a user