1
0
forked from boostorg/move

Fixes #45 ("Sort/merge bugs that affect boost::container::flat_map")

This commit is contained in:
Ion Gaztañaga
2021-11-03 15:44:44 +01:00
parent 70623d0215
commit a51c5cc218
4 changed files with 48 additions and 36 deletions

View File

@@ -802,6 +802,13 @@ Special thanks to:
[section:release_notes Release Notes] [section:release_notes Release Notes]
[section:release_notes_boost_1_78 Boost 1.78 Release]
* Fixed bugs:
* [@https://github.com/boostorg/move/issues/45 Git Issue #45: ['"Sort/merge bugs that affect boost::container::flat_map"]].
[endsect]
[section:release_notes_boost_1_77 Boost 1.77 Release] [section:release_notes_boost_1_77 Boost 1.77 Release]
* Fixed bugs: * Fixed bugs:

View File

@@ -453,9 +453,9 @@ bool adaptive_sort_build_params
l_build_buf = size_type(l_intbuf*2); l_build_buf = size_type(l_intbuf*2);
n_keys = l_intbuf; n_keys = l_intbuf;
} }
else if(collected == (n_min_ideal_keys+l_intbuf)){ else if(collected >= (n_min_ideal_keys+l_intbuf)){
l_build_buf = l_intbuf; l_build_buf = l_intbuf;
n_keys = n_min_ideal_keys; n_keys = size_type(collected - l_intbuf);
} }
//If collected keys are not enough, try to fix n_keys and l_intbuf. If no fix //If collected keys are not enough, try to fix n_keys and l_intbuf. If no fix
//is possible (due to very low unique keys), then go to a slow sort based on rotations. //is possible (due to very low unique keys), then go to a slow sort based on rotations.

View File

@@ -863,22 +863,20 @@ template<typename BidirectionalIterator,
typedef typename iterator_traits<BidirectionalIterator>::size_type size_type; typedef typename iterator_traits<BidirectionalIterator>::size_type size_type;
//trivial cases //trivial cases
if (!len2 || !len1) { if (!len2 || !len1) {
return; // no-op
} }
else if (len1 <= buffer_size || len2 <= buffer_size) else if (len1 <= buffer_size || len2 <= buffer_size) {
{
range_xbuf<Pointer, size_type, move_op> rxbuf(buffer, buffer + buffer_size); range_xbuf<Pointer, size_type, move_op> rxbuf(buffer, buffer + buffer_size);
buffered_merge(first, middle, last, comp, rxbuf); buffered_merge(first, middle, last, comp, rxbuf);
} }
else if (size_type(len1 + len2) == 2u) { else if (size_type(len1 + len2) == 2u) {
if (comp(*middle, *first)) if (comp(*middle, *first))
adl_move_swap(*first, *middle); adl_move_swap(*first, *middle);
return;
} }
else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) { else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) {
merge_bufferless_ON2(first, middle, last, comp); merge_bufferless_ON2(first, middle, last, comp);
return;
} }
else {
BidirectionalIterator first_cut = first; BidirectionalIterator first_cut = first;
BidirectionalIterator second_cut = middle; BidirectionalIterator second_cut = middle;
size_type len11 = 0; size_type len11 = 0;
@@ -907,6 +905,7 @@ template<typename BidirectionalIterator,
merge_adaptive_ONlogN_recursive(new_middle, second_cut, last, merge_adaptive_ONlogN_recursive(new_middle, second_cut, last,
size_type(len1 - len11), size_type(len2 - len22), buffer, buffer_size, comp); size_type(len1 - len11), size_type(len2 - len22), buffer, buffer_size, comp);
} }
}
template<typename BidirectionalIterator, typename Compare, typename RandRawIt> template<typename BidirectionalIterator, typename Compare, typename RandRawIt>

View File

@@ -74,9 +74,15 @@ int main()
instantiate_smalldiff_iterators(); instantiate_smalldiff_iterators();
const std::size_t NIter = 100; const std::size_t NIter = 100;
//Below absolute minimal unique values
test_random_shuffled<order_move_type>(10001, 3, NIter); test_random_shuffled<order_move_type>(10001, 3, NIter);
//Above absolute minimal unique values, below internal buffer
test_random_shuffled<order_move_type>(10001, 65, NIter); test_random_shuffled<order_move_type>(10001, 65, NIter);
//Enough keys for internal buffer but below minimal keys
test_random_shuffled<order_move_type>(10001, 101, NIter); test_random_shuffled<order_move_type>(10001, 101, NIter);
//Enough keys for internal buffer and above minimal keys
test_random_shuffled<order_move_type>(10001, 200, NIter);
//Enough keys for internal buffer, and full keys
test_random_shuffled<order_move_type>(10001, 1023, NIter); test_random_shuffled<order_move_type>(10001, 1023, NIter);
test_random_shuffled<order_move_type>(10001, 4095, NIter); test_random_shuffled<order_move_type>(10001, 4095, NIter);
test_random_shuffled<order_move_type>(10001, 0, NIter); test_random_shuffled<order_move_type>(10001, 0, NIter);