forked from boostorg/move
Fixes #45 ("Sort/merge bugs that affect boost::container::flat_map")
This commit is contained in:
@@ -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:
|
||||||
|
@@ -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.
|
||||||
|
@@ -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>
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user