diff --git a/include/boost/move/algo/adaptive_merge.hpp b/include/boost/move/algo/adaptive_merge.hpp index 4de4007..f907b5c 100644 --- a/include/boost/move/algo/adaptive_merge.hpp +++ b/include/boost/move/algo/adaptive_merge.hpp @@ -107,32 +107,15 @@ inline void adaptive_merge_final_merge( RandIt first { typedef typename iterator_traits::size_type size_type; (void)l_block; + (void)use_internal_buf; size_type n_keys = collected-l_intbuf; size_type len = len1+len2; - if(use_internal_buf){ - if(xbuf_used){ - xbuf.clear(); - //Nothing to do - if(n_keys){ - unstable_sort(first, first+n_keys, comp, xbuf); - stable_merge(first, first+n_keys, first+len, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A key mrg: ", len); - } - } - else{ - xbuf.clear(); - unstable_sort(first, first+collected, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len); - stable_merge(first, first+collected, first+len, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len); - } - } - else{ + if (!xbuf_used || n_keys) { xbuf.clear(); - unstable_sort(first, first+collected, comp, xbuf); + const size_type middle = xbuf_used && n_keys ? n_keys: collected; + unstable_sort(first, first + middle, comp, xbuf); BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b srt: ", len); - stable_merge(first, first+collected, first+len1+len2, comp, xbuf); - BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(" A k/b mrg: ", len); + stable_merge(first, first + middle, first + len, comp, xbuf); } BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(" A fin mrg: ", len); } @@ -168,8 +151,8 @@ inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, size_type l_block = rl_block; size_type l_intbuf = xbuf.capacity() >= l_block ? 0u : l_block; - while(xbuf.capacity() >= l_block*2){ - l_block *= 2; + if (xbuf.capacity() > l_block){ + l_block = xbuf.capacity(); } //This is the minimum number of keys to implement the ideal algorithm @@ -331,7 +314,33 @@ void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp typedef typename iterator_traits::size_type size_type; typedef typename iterator_traits::value_type value_type; - ::boost::movelib::detail_adaptive::adaptive_xbuf xbuf(uninitialized, uninitialized_len); + if (first == middle || middle == last){ + return; + } + + //Reduce ranges to merge if possible + do { + if (comp(*middle, *first)){ + break; + } + ++first; + if (first == middle) + return; + } while(1); + + RandIt first_high(middle); + --first_high; + do { + --last; + if (comp(*last, *first_high)){ + ++last; + break; + } + if (last == middle) + return; + } while(1); + + ::boost::movelib::adaptive_xbuf xbuf(uninitialized, uninitialized_len); ::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf); }