mirror of
https://github.com/boostorg/move.git
synced 2025-07-31 21:04:27 +02:00
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_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]
|
||||
|
||||
* Fixed bugs:
|
||||
|
@@ -453,9 +453,9 @@ bool adaptive_sort_build_params
|
||||
l_build_buf = size_type(l_intbuf*2);
|
||||
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;
|
||||
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
|
||||
//is possible (due to very low unique keys), then go to a slow sort based on rotations.
|
||||
|
@@ -863,49 +863,48 @@ template<typename BidirectionalIterator,
|
||||
typedef typename iterator_traits<BidirectionalIterator>::size_type size_type;
|
||||
//trivial cases
|
||||
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);
|
||||
buffered_merge(first, middle, last, comp, rxbuf);
|
||||
}
|
||||
else if (size_type(len1 + len2) == 2u) {
|
||||
if (comp(*middle, *first))
|
||||
adl_move_swap(*first, *middle);
|
||||
return;
|
||||
}
|
||||
else if (size_type(len1 + len2) < MergeBufferlessONLogNRotationThreshold) {
|
||||
merge_bufferless_ON2(first, middle, last, comp);
|
||||
return;
|
||||
}
|
||||
BidirectionalIterator first_cut = first;
|
||||
BidirectionalIterator second_cut = middle;
|
||||
size_type len11 = 0;
|
||||
size_type len22 = 0;
|
||||
if (len1 > len2) //(len1 < len2)
|
||||
{
|
||||
len11 = len1 / 2;
|
||||
first_cut += len11;
|
||||
second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp);
|
||||
len22 = size_type(second_cut - middle);
|
||||
}
|
||||
else
|
||||
{
|
||||
len22 = len2 / 2;
|
||||
second_cut += len22;
|
||||
first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp);
|
||||
len11 = size_type(first_cut - first);
|
||||
}
|
||||
else {
|
||||
BidirectionalIterator first_cut = first;
|
||||
BidirectionalIterator second_cut = middle;
|
||||
size_type len11 = 0;
|
||||
size_type len22 = 0;
|
||||
if (len1 > len2) //(len1 < len2)
|
||||
{
|
||||
len11 = len1 / 2;
|
||||
first_cut += len11;
|
||||
second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp);
|
||||
len22 = size_type(second_cut - middle);
|
||||
}
|
||||
else
|
||||
{
|
||||
len22 = len2 / 2;
|
||||
second_cut += len22;
|
||||
first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp);
|
||||
len11 = size_type(first_cut - first);
|
||||
}
|
||||
|
||||
BidirectionalIterator new_middle
|
||||
= rotate_adaptive(first_cut, middle, second_cut,
|
||||
size_type(len1 - len11), len22, buffer,
|
||||
buffer_size);
|
||||
merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11,
|
||||
len22, buffer, buffer_size, comp);
|
||||
merge_adaptive_ONlogN_recursive(new_middle, second_cut, last,
|
||||
size_type(len1 - len11), size_type(len2 - len22), buffer, buffer_size, comp);
|
||||
BidirectionalIterator new_middle
|
||||
= rotate_adaptive(first_cut, middle, second_cut,
|
||||
size_type(len1 - len11), len22, buffer,
|
||||
buffer_size);
|
||||
merge_adaptive_ONlogN_recursive(first, first_cut, new_middle, len11,
|
||||
len22, buffer, buffer_size, comp);
|
||||
merge_adaptive_ONlogN_recursive(new_middle, second_cut, last,
|
||||
size_type(len1 - len11), size_type(len2 - len22), buffer, buffer_size, comp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -74,9 +74,15 @@ int main()
|
||||
instantiate_smalldiff_iterators();
|
||||
|
||||
const std::size_t NIter = 100;
|
||||
test_random_shuffled<order_move_type>(10001, 3, NIter);
|
||||
test_random_shuffled<order_move_type>(10001, 65, NIter);
|
||||
test_random_shuffled<order_move_type>(10001, 101, NIter);
|
||||
//Below absolute minimal unique values
|
||||
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);
|
||||
//Enough keys for internal buffer but below minimal keys
|
||||
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, 4095, NIter);
|
||||
test_random_shuffled<order_move_type>(10001, 0, NIter);
|
||||
|
Reference in New Issue
Block a user