From ee0bf8bb74b1f13847517bc0fc3d71934ec86b20 Mon Sep 17 00:00:00 2001 From: spreadsort Date: Sat, 28 Jan 2023 19:48:48 -0500 Subject: [PATCH 01/17] Fix sort.idx line endings --- doc/sort.idx | 74 ++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/doc/sort.idx b/doc/sort.idx index 4492743..2453517 100644 --- a/doc/sort.idx +++ b/doc/sort.idx @@ -1,37 +1,37 @@ -# sort.idx for Boost.Sort/Spreadsort Quickbook, Doxygen and Auto-index. - -# Note needs more customization to be useful in practice! TODO? - -#!debug "\<\w*\>" - -# Sort Header files. -#!scan-path "/boost/sort/" ".*\.*pp" true -!scan-path "../include/boost/sort" ".*\.hpp" false -!scan-path "../include/boost/sort/spreadsort" ".*\.hpp" false - -# All example source files, assuming no sub-folders. -# sort example files. -!scan-path "../example" ".*\.cpp" true - -# Allow alternative spellings colour | color, and plurals etc. -color \<\w*(colour|color)\w*\> -container \ -data -deque \ -example \ -font \ -greek -quartile \ -histogram -ioflags -origin -outlier -maximum \ -minimum \ -precision -range \<\w*\range\w*\> -scaling \<\w*\scal\w*\> -tick \<\w*\tick\w*\> -title -Unicode \ -vector \<\w*\vector\w*\> +# sort.idx for Boost.Sort/Spreadsort Quickbook, Doxygen and Auto-index. + +# Note needs more customization to be useful in practice! TODO? + +#!debug "\<\w*\>" + +# Sort Header files. +#!scan-path "/boost/sort/" ".*\.*pp" true +!scan-path "../include/boost/sort" ".*\.hpp" false +!scan-path "../include/boost/sort/spreadsort" ".*\.hpp" false + +# All example source files, assuming no sub-folders. +# sort example files. +!scan-path "../example" ".*\.cpp" true + +# Allow alternative spellings colour | color, and plurals etc. +color \<\w*(colour|color)\w*\> +container \ +data +deque \ +example \ +font \ +greek +quartile \ +histogram +ioflags +origin +outlier +maximum \ +minimum \ +precision +range \<\w*\range\w*\> +scaling \<\w*\scal\w*\> +tick \<\w*\tick\w*\> +title +Unicode \ +vector \<\w*\vector\w*\> From 641c2f02b5febbf1ad51f38d0a96afd8968bd5d0 Mon Sep 17 00:00:00 2001 From: spreadsort Date: Sun, 29 Jan 2023 20:41:07 -0500 Subject: [PATCH 02/17] Clarify pdqsort documentation and add to doxygen --- doc/Jamfile.v2 | 1 + doc/pdqsort.qbk | 3 ++- doc/sort.idx | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index adc100b..672a200 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -52,6 +52,7 @@ doxygen autodoc : [ glob $(here)/../include/boost/sort.hpp ] [ glob $(here)/../include/boost/sort/spreadsort/*.hpp ] + [ glob $(here)/../include/boost/sort/pdqsort/pdqsort.hpp ] # [ glob $(here)/../include/boost/sort/detail/spreadsort/*.hpp ] # Hide implementation/detail for now. # but could also include this and switch Boost.Sort C++ reference info to include implementation/detail or not using Doxygen macro DETAIL. # See http://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdcond diff --git a/doc/pdqsort.qbk b/doc/pdqsort.qbk index fc94ed1..adf4750 100644 --- a/doc/pdqsort.qbk +++ b/doc/pdqsort.qbk @@ -32,7 +32,8 @@ introsort. It is identical in usage to __std_sort. Pattern-defeating quicksort is available through two calls, __pdqsort and __pdqsort_branchless. Both have identical guarantees, behavior and overloads as __std_sort, with the exception of the C++17 -parallel execution policy argument. Thus you can simply replace a call to __std_sort with __pdqsort, +parallel execution policy argument. Thus you can replace a call to __std_sort with +boost::sort::pdqsort, available from boost/sort/pdqsort/pdqsort.hpp, it is simply a faster implementation. It is almost always appropriate to simply call __pdqsort and ignore __pdqsort_branchless. diff --git a/doc/sort.idx b/doc/sort.idx index 2453517..b44406b 100644 --- a/doc/sort.idx +++ b/doc/sort.idx @@ -8,6 +8,7 @@ #!scan-path "/boost/sort/" ".*\.*pp" true !scan-path "../include/boost/sort" ".*\.hpp" false !scan-path "../include/boost/sort/spreadsort" ".*\.hpp" false +!scan-path "../include/boost/sort/pdqsort" ".*\.hpp" false # All example source files, assuming no sub-folders. # sort example files. From 6df06af708ed619d3320b5e990c6c896e20a2aa6 Mon Sep 17 00:00:00 2001 From: spreadsort Date: Sun, 29 Jan 2023 20:47:00 -0500 Subject: [PATCH 03/17] Mention include requirements --- doc/introduction.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/introduction.qbk b/doc/introduction.qbk index 714b751..1967934 100644 --- a/doc/introduction.qbk +++ b/doc/introduction.qbk @@ -14,7 +14,8 @@ The goal of the Boost Sort Library is provide to the users, the most modern, fas This library provides stable and unstable sorting algorithms, in single threaded and parallel versions. -These algorithms do not use any other library or utility. The parallel algorithms need a C++11 compliant compiler. +These algorithms do not use any other library or utility, you only need to include boost/sort/sort.hpp +or one of the more specific headers. The parallel algorithms need a C++11 compliant compiler. [h4[_Single Thread Algorithms]] From 82ef138385399bb3de323885e71f3c7a23d13313 Mon Sep 17 00:00:00 2001 From: spreadsort Date: Thu, 20 Apr 2023 19:09:34 -0400 Subject: [PATCH 04/17] Fix overflow issue with signed subtraction in float_sort Also fix a problem with windows running tune.pl --- include/boost/sort/spreadsort/detail/float_sort.hpp | 6 +++--- tune.pl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/sort/spreadsort/detail/float_sort.hpp b/include/boost/sort/spreadsort/detail/float_sort.hpp index 8682afd..2fb903f 100644 --- a/include/boost/sort/spreadsort/detail/float_sort.hpp +++ b/include/boost/sort/spreadsort/detail/float_sort.hpp @@ -410,7 +410,7 @@ namespace spreadsort { max, min)) return; unsigned log_divisor = get_log_divisor( - last - first, rough_log_2_size(Size_type(max - min))); + last - first, rough_log_2_size(Size_type(max/2 - min/2)) + 1); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; @@ -507,7 +507,7 @@ namespace spreadsort { if (is_sorted_or_find_extremes(first, last, max, min, rshift)) return; unsigned log_divisor = get_log_divisor( - last - first, rough_log_2_size(Size_type(max - min))); + last - first, rough_log_2_size(Size_type(max/2 - min/2)) + 1); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; @@ -605,7 +605,7 @@ namespace spreadsort { if (is_sorted_or_find_extremes(first, last, max, min, rshift, comp)) return; unsigned log_divisor = get_log_divisor( - last - first, rough_log_2_size(Size_type(max - min))); + last - first, rough_log_2_size(Size_type(max/2 - min/2)) + 1); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; diff --git a/tune.pl b/tune.pl index 598f1a9..4f83ce7 100755 --- a/tune.pl +++ b/tune.pl @@ -19,7 +19,7 @@ $verifycorrect = 0; $verbose = 0; $exename = "spreadsort"; -$makename = "../../b2 \-\-tune"; +$makename = "b2 \-\-tune"; $all = ""; $iter_count = 1; $debug = 0; From 0386b327fc4eb1eb1585f7d1c23a6c067744d757 Mon Sep 17 00:00:00 2001 From: Mark Melton Date: Tue, 6 Jun 2023 17:24:40 -0400 Subject: [PATCH 05/17] Apply `use std::swap` idiom for all calls to `std::swap` --- .../blk_detail/parallel_sort.hpp | 8 +++-- .../block_indirect_sort.hpp | 3 +- include/boost/sort/common/merge_four.hpp | 34 ++++++++++--------- include/boost/sort/common/pivot.hpp | 13 ++++--- include/boost/sort/common/rearrange.hpp | 3 +- .../parallel_stable_sort.hpp | 3 +- .../boost/sort/sample_sort/sample_sort.hpp | 3 +- include/boost/sort/spinsort/spinsort.hpp | 9 +++-- 8 files changed, 45 insertions(+), 31 deletions(-) diff --git a/include/boost/sort/block_indirect_sort/blk_detail/parallel_sort.hpp b/include/boost/sort/block_indirect_sort/blk_detail/parallel_sort.hpp index 71c74e6..69dfa5b 100644 --- a/include/boost/sort/block_indirect_sort/blk_detail/parallel_sort.hpp +++ b/include/boost/sort/block_indirect_sort/blk_detail/parallel_sort.hpp @@ -134,6 +134,7 @@ parallel_sort ::parallel_sort(backbone_t &bkbn, Iter_t first, Iter_t last) : bk(bkbn), counter(0) { + using std::swap; assert((last - first) >= 0); size_t nelem = size_t(last - first); @@ -153,7 +154,7 @@ ::parallel_sort(backbone_t &bkbn, Iter_t first, Iter_t last) size_t nelem2 = nelem >> 1; Iter_t it1 = first, it2 = last - 1; for (size_t i = 0; i < nelem2; ++i) - std::swap(*(it1++), *(it2--)); + swap(*(it1++), *(it2--)); return; }; @@ -188,6 +189,7 @@ template void parallel_sort ::divide_sort(Iter_t first, Iter_t last, uint32_t level) { + using std::swap; //------------------- check if sort ----------------------------------- bool sorted = true; for (Iter_t it1 = first, it2 = first + 1; @@ -211,14 +213,14 @@ ::divide_sort(Iter_t first, Iter_t last, uint32_t level) while (c_first < c_last) { - std::swap(*(c_first++), *(c_last--)); + swap(*(c_first++), *(c_last--)); while (bk.cmp(*c_first, val)) ++c_first; while (bk.cmp(val, *c_last)) --c_last; }; - std::swap(*first, *c_last); + swap(*first, *c_last); // insert the work of the second half in the stack of works function_divide_sort(c_first, last, level - 1, counter, bk.error); diff --git a/include/boost/sort/block_indirect_sort/block_indirect_sort.hpp b/include/boost/sort/block_indirect_sort/block_indirect_sort.hpp index 04ea42f..5e03b28 100644 --- a/include/boost/sort/block_indirect_sort/block_indirect_sort.hpp +++ b/include/boost/sort/block_indirect_sort/block_indirect_sort.hpp @@ -216,7 +216,8 @@ ::block_indirect_sort(Iter_t first, Iter_t last, Compare cmp, uint32_t nthr) Iter_t it1 = first, it2 = last - 1; for (size_t i = 0; i < nelem2; ++i) { - std::swap(*(it1++), *(it2--)); + using std::swap; + swap(*(it1++), *(it2--)); }; return; }; diff --git a/include/boost/sort/common/merge_four.hpp b/include/boost/sort/common/merge_four.hpp index 6b791be..ce3f5e5 100644 --- a/include/boost/sort/common/merge_four.hpp +++ b/include/boost/sort/common/merge_four.hpp @@ -76,6 +76,7 @@ range full_merge4(const range &rdest, range vrange_input[4], uint32_t nrange_input, Compare comp) { + using std::swap; typedef range range1_t; typedef util::value_iter type1; typedef util::value_iter type2; @@ -120,28 +121,28 @@ range full_merge4(const range &rdest, if (less_range(vrange_input[pos[1]].first, pos[1], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[1]); + swap(pos[0], pos[1]); }; if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3], vrange_input[pos[2]].first, pos[2], comp)) { - std::swap(pos[3], pos[2]); + swap(pos[3], pos[2]); }; if (less_range (vrange_input[pos[2]].first, pos[2], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[2]); + swap(pos[0], pos[2]); }; if (npos == 4 and less_range (vrange_input[pos[3]].first, pos[3], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[3]); + swap(pos[1], pos[3]); }; if (less_range (vrange_input[pos[2]].first, pos[2], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[2]); + swap(pos[1], pos[2]); }; Iter1_t it_dest = rdest.first; @@ -160,18 +161,18 @@ range full_merge4(const range &rdest, if (less_range(vrange_input[pos[1]].first, pos[1], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[1]); + swap(pos[0], pos[1]); if (less_range(vrange_input[pos[2]].first, pos[2], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[2]); + swap(pos[1], pos[2]); if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3], vrange_input[pos[2]].first, pos[2], comp)) { - std::swap(pos[2], pos[3]); + swap(pos[2], pos[3]); }; }; }; @@ -208,6 +209,7 @@ range uninit_full_merge4(const range &dest, range vrange_input[4], uint32_t nrange_input, Compare comp) { + using std::swap; typedef util::value_iter type1; static_assert (std::is_same< type1, Value_t >::value, "Incompatible iterators\n"); @@ -248,27 +250,27 @@ range uninit_full_merge4(const range &dest, if (less_range(vrange_input[pos[1]].first, pos[1], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[1]); + swap(pos[0], pos[1]); }; if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3], vrange_input[pos[2]].first, pos[2], comp)) { - std::swap(pos[3], pos[2]); + swap(pos[3], pos[2]); }; if (less_range(vrange_input[pos[2]].first, pos[2], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[2]); + swap(pos[0], pos[2]); }; if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[3]); + swap(pos[1], pos[3]); }; if (less_range(vrange_input[pos[2]].first, pos[2], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[2]); + swap(pos[1], pos[2]); }; Value_t *it_dest = dest.first; @@ -288,17 +290,17 @@ range uninit_full_merge4(const range &dest, if (less_range (vrange_input[pos[1]].first, pos[1], vrange_input[pos[0]].first, pos[0], comp)) { - std::swap(pos[0], pos[1]); + swap(pos[0], pos[1]); if (less_range (vrange_input[pos[2]].first, pos[2], vrange_input[pos[1]].first, pos[1], comp)) { - std::swap(pos[1], pos[2]); + swap(pos[1], pos[2]); if (npos == 4 and less_range(vrange_input[pos[3]].first, pos[3], vrange_input[pos[2]].first, pos[2], comp)) { - std::swap(pos[2], pos[3]); + swap(pos[2], pos[3]); }; }; }; diff --git a/include/boost/sort/common/pivot.hpp b/include/boost/sort/common/pivot.hpp index 6422a34..7b10385 100644 --- a/include/boost/sort/common/pivot.hpp +++ b/include/boost/sort/common/pivot.hpp @@ -43,10 +43,11 @@ namespace common template < typename Iter_t, typename Compare > inline Iter_t mid3 (Iter_t iter_1, Iter_t iter_2, Iter_t iter_3, Compare comp) { - if (comp (*iter_2, *iter_1)) std::swap ( *iter_2, *iter_1); + using std::swap; + if (comp (*iter_2, *iter_1)) swap ( *iter_2, *iter_1); if (comp (*iter_3, *iter_2)) - { std::swap ( *iter_3, *iter_2); - if (comp (*iter_2, *iter_1)) std::swap ( *iter_2, *iter_1); + { swap ( *iter_3, *iter_2); + if (comp (*iter_2, *iter_1)) swap ( *iter_2, *iter_1); }; return iter_2; }; @@ -64,9 +65,10 @@ inline Iter_t mid3 (Iter_t iter_1, Iter_t iter_2, Iter_t iter_3, Compare comp) template < class Iter_t, class Compare > inline void pivot3 (Iter_t first, Iter_t last, Compare comp) { + using std::swap; auto N2 = (last - first) >> 1; Iter_t it_val = mid3 (first + 1, first + N2, last - 1, comp); - std::swap (*first, *it_val); + swap (*first, *it_val); }; // @@ -110,11 +112,12 @@ inline Iter_t mid9 (Iter_t iter_1, Iter_t iter_2, Iter_t iter_3, Iter_t iter_4, template < class Iter_t, class Compare > inline void pivot9 (Iter_t first, Iter_t last, Compare comp) { + using std::swap; size_t cupo = (last - first) >> 3; Iter_t itaux = mid9 (first + 1, first + cupo, first + 2 * cupo, first + 3 * cupo, first + 4 * cupo, first + 5 * cupo, first + 6 * cupo, first + 7 * cupo, last - 1, comp); - std::swap (*first, *itaux); + swap (*first, *itaux); }; //**************************************************************************** };// End namespace common diff --git a/include/boost/sort/common/rearrange.hpp b/include/boost/sort/common/rearrange.hpp index fe48ee6..d32db09 100644 --- a/include/boost/sort/common/rearrange.hpp +++ b/include/boost/sort/common/rearrange.hpp @@ -92,8 +92,9 @@ void rearrange(Iter_data global_first, Iter_index itx_first, while ((pos_src = pos(itx_src)) != pos_ini) { + using std::swap; data[pos_dest] = std::move(data[pos_src]); - std::swap(itx_src, index[pos_src]); + swap(itx_src, index[pos_src]); pos_dest = pos_src; }; diff --git a/include/boost/sort/parallel_stable_sort/parallel_stable_sort.hpp b/include/boost/sort/parallel_stable_sort/parallel_stable_sort.hpp index 9f1ada1..cd68557 100644 --- a/include/boost/sort/parallel_stable_sort/parallel_stable_sort.hpp +++ b/include/boost/sort/parallel_stable_sort/parallel_stable_sort.hpp @@ -150,10 +150,11 @@ ::parallel_stable_sort (Iter_t first, Iter_t last, Compare comp, it2 != last and (sw = comp(*it2, *it1)); it1 = it2++); if (sw) { + using std::swap; size_t nelem2 = nelem >> 1; Iter_t it1 = first, it2 = last - 1; for (size_t i = 0; i < nelem2; ++i) - std::swap(*(it1++), *(it2--)); + swap(*(it1++), *(it2--)); return; }; diff --git a/include/boost/sort/sample_sort/sample_sort.hpp b/include/boost/sort/sample_sort/sample_sort.hpp index c5b4cb9..e52e2dd 100644 --- a/include/boost/sort/sample_sort/sample_sort.hpp +++ b/include/boost/sort/sample_sort/sample_sort.hpp @@ -273,10 +273,11 @@ ::sample_sort (Iter_t first, Iter_t last, Compare cmp, uint32_t num_thread, it2 != last and (sw = comp(*it2, *it1)); it1 = it2++); if (sw) { + using std::swap; size_t nelem2 = nelem >> 1; Iter_t it1 = first, it2 = last - 1; for (size_t i = 0; i < nelem2; ++i) - std::swap(*(it1++), *(it2--)); + swap(*(it1++), *(it2--)); return; }; diff --git a/include/boost/sort/spinsort/spinsort.hpp b/include/boost/sort/spinsort/spinsort.hpp index 726341b..b8d0fdf 100644 --- a/include/boost/sort/spinsort/spinsort.hpp +++ b/include/boost/sort/spinsort/spinsort.hpp @@ -209,8 +209,10 @@ static bool check_stable_sort(const range &rng_data, size_t nreverse = it2 - rng_data.first; Iter1_t alpha(rng_data.first), beta(it2 - 1), mid( rng_data.first + (nreverse >> 1)); - while (alpha != mid) - std::swap(*(alpha++), *(beta--)); + while (alpha != mid) { + using std::swap; + swap(*(alpha++), *(beta--)); + } // insert the elements between it1 and last if (it2 != rng_data.last) @@ -470,10 +472,11 @@ ::spinsort (Iter_t first, Iter_t last, Compare comp, value_t *paux, size_t naux) it2 != last and (sw = comp(*it2, *it1)); it1 = it2++); if (sw) { + using std::swap; size_t nelem2 = nelem >> 1; Iter_t it1 = first, it2 = last - 1; for (size_t i = 0; i < nelem2; ++i) - std::swap(*(it1++), *(it2--)); + swap(*(it1++), *(it2--)); return; }; From f9080299c391d0c85ffcf21e4afca463034fa2a7 Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Sat, 26 Aug 2023 18:04:49 +1000 Subject: [PATCH 06/17] Markdown conversion for README.md --- README.md | 72 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index c7588c2..49aa16e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -

BOOST SORT

+# BOOST SORT -

Introduction

+## Introduction The goal of the Boost Sort Library is provide to the users, the most modern and fast sorting algorithms. @@ -8,72 +8,74 @@ This library provides stable and not stable sorting algorithms, in single thread These algorithms do not use any other library or utility. The parallel algorithms need a C++11 compliant compiler. -

Single Thread Algorithms

+Detailed [boost API documentation](https://www.boost.org/doc/libs/release/libs/sort/) also available. +## Single Thread Algorithms - | | | | | - Algorithm |Stable | Additional memory |Best, average, and worst case | Comparison method | - ------------------|-------|----------------------------|-------------------------------|---------------------| - spreadsort | no | key_length | N, N sqrt(LogN), | Hybrid radix sort | - | | | min(N logN, N key_length) | | - pdqsort | no | Log N | N, N LogN, N LogN | Comparison operator | - spinsort | yes | N / 2 | N, N LogN, N LogN | Comparison operator | - flat_stable_sort | yes |size of the data / 256 + 8K | N, N LogN, N LogN | Comparison operator | - | | | | | + | Algorithm |Stable | Additional memory |Best, average, and worst case | Comparison method | + |-------------------|-------|----------------------------|-------------------------------|---------------------| + | spreadsort | no | key_length | N, N sqrt(LogN), | Hybrid radix sort | + | | | | min(N logN, N key_length) | | + | pdqsort | no | Log N | N, N LogN, N LogN | Comparison operator | + | spinsort | yes | N / 2 | N, N LogN, N LogN | Comparison operator | + | flat_stable_sort | yes |size of the data / 256 + 8K | N, N LogN, N LogN | Comparison operator | -- **spreadsort** is a novel hybrid radix sort algorithm, extremely fast, designed and developed by Steven Ross. -- **pdqsort** is a improvement of the quick sort algorithm, designed and developed by Orson Peters. +- **spreadsort** is a [novel hybrid radix sort algorithm](https://en.wikipedia.org/wiki/Spreadsort), extremely fast, designed and developed by Steven Ross. + [(paper)](doc/papers/original_spreadsort06_2002.pdf) + +- **pdqsort** is a [improvement of the quick sort algorithm](https://en.wikipedia.org/wiki/Introsort#pdqsort), designed and developed by Orson Peters. + [(paper)](https://arxiv.org/pdf/2106.05123.pdf) - **spinsort** is a stable sort, fast with random and with near sorted data, designed and developed by Francisco Tapia. - **flat_stable_sort** stable sort with a small additional memory (around 1% of the size of the data), provide the 80% - 90% of the speed of spinsort, being fast with random and with near sorted data, designed and developed by Francisco Tapia. + [(paper)](doc/papers/flat_stable_sort_eng.pdf) -

Parallel Algorithms

+## Parallel Algorithms - | | | | - Algorithm |Stable | Additional memory |Best, average, and worst case | - ----------------------|-------|------------------------|------------------------------| - block_indirect_sort | no |block_size * num_threads| N, N LogN , N LogN | - sample_sort | yes | N | N, N LogN , N LogN | - parallel_stable_sort | yes | N / 2 | N, N LogN , N LogN | - | | | | + | Algorithm |Stable | Additional memory |Best, average, and worst case | + |-----------------------|-------|------------------------|------------------------------| + | block_indirect_sort | no |block_size * num_threads| N, N LogN , N LogN | + | sample_sort | yes | N | N, N LogN , N LogN | + | parallel_stable_sort | yes | N / 2 | N, N LogN , N LogN | -- **Sample_sort** is a implementation of the [Samplesort algorithm](https://en.wikipedia.org/wiki/Samplesort) done by Francisco Tapia. +- **Sample_sort** is a implementation of the [Samplesort algorithm](https://en.wikipedia.org/wiki/Samplesort) done by Francisco Tapia. - **Parallel_stable_sort** is based on the samplesort algorithm, but using a half of the memory used by sample_sort, conceived and implemented by Francisco Tapia. - **Block_indirect_sort** is a novel parallel sort algorithm, very fast, with low additional memory consumption, conceived and implemented by Francisco Tapia. + [(paper)](doc/papers/block_indirect_sort_en.pdf) The **block_size** is an internal parameter of the algorithm, which in order to achieve the highest speed, changes according to the size of the objects to sort according to the next table. The strings use a block_size of 128. - | | | | | | | | - object size (bytes) | 1 - 15 | 16 - 31 | 32 - 63 | 64 - 127|128 - 255|256 - 511| 512 - | - --------------------------------|--------|---------|---------|---------|---------|---------|----------| - block_size (number of elements) | 4096 | 2048 | 1024 | 768 | 512 | 256 | 128 | - | | | | | | | | + | object size (bytes) | 1 - 15 | 16 - 31 | 32 - 63 | 64 - 127|128 - 255|256 - 511| 512 - | + |---------------------------------|--------|---------|---------|---------|---------|---------|----------| + | block_size (number of elements) | 4096 | 2048 | 1024 | 768 | 512 | 256 | 128 | + +## Installation -

Installation

- This library is **include only**. - Don't need to link with any static or dynamic library. Only need a C++11 compiler - Only need to include the file boost/sort/sort.hpp -

Author and Copyright

-This library is integrated in the [Boost Library](https://boost.org) . +## Author and Copyright + +This library is integrated in the [Boost Library](https://boost.org). Copyright 2017 -- [Steven Ross *(spreadsort@gmail.com)* ](mail:spreadsort@gmail.com) -- [Francisco Tapia *(fjtapia@gmail.com)* ](mail:fjtapia@gmail.com) -- [Orson Peters *(orsonpeters@gmail.com)* ](mail:orsonpeters@gmail.com) +- [Steven Ross](mailto:spreadsort@gmail.com) +- [Francisco Tapia](mailto:fjtapia@gmail.com) +- [Orson Peters](mailto:orsonpeters@gmail.com) -Distributed under the [Boost Software License, Version 1.0. ](http://www.boost.org/LICENSE_1_0.txt) (See http://www.boost.org/LICENSE_1_0.txt) +Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). From 531d497707f603df2eda259a0d6468aa3764a568 Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Tue, 29 Aug 2023 10:12:35 +0200 Subject: [PATCH 07/17] Add files via upload Check with empty ranges --- test/test_block_indirect_sort.cpp | 5 ++++- test/test_flat_stable_sort.cpp | 2 ++ test/test_insert_sort.cpp | 4 ++++ test/test_parallel_stable_sort.cpp | 4 ++++ test/test_sample_sort.cpp | 3 +++ test/test_spinsort.cpp | 4 ++++ 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/test/test_block_indirect_sort.cpp b/test/test_block_indirect_sort.cpp index b03f00f..05f63cf 100644 --- a/test/test_block_indirect_sort.cpp +++ b/test/test_block_indirect_sort.cpp @@ -37,8 +37,11 @@ void test1 (void) std::vector< uint64_t > V1; V1.reserve (NElem); + //------------------- sort 0 elements ------------------------------------ + block_indirect_sort ( V1.end (), V1.end ( ), 4); + //------------------ sorted elements 4 threads -------------------------- - V1.clear ( ); + V1.clear (); for (uint32_t i = 0; i < NElem; ++i) V1.push_back (i); block_indirect_sort ( V1.begin ( ), V1.end ( ), 4); diff --git a/test/test_flat_stable_sort.cpp b/test/test_flat_stable_sort.cpp index 83aaaad..d1df52c 100644 --- a/test/test_flat_stable_sort.cpp +++ b/test/test_flat_stable_sort.cpp @@ -53,6 +53,8 @@ void test1 ( ) V1.push_back (G); }; }; + //check sort 0 elements + flat_stable_sort< iter_t, compare_t > (V1.begin ( ), V1.begin ( ), compare_t ( )); V2 = V1; flat_stable_sort< iter_t, compare_t > (V1.begin ( ), V1.end ( ), compare_t ( )); std::stable_sort (V2.begin ( ), V2.end ( )); diff --git a/test/test_insert_sort.cpp b/test/test_insert_sort.cpp index c2b93db..34e7785 100644 --- a/test/test_insert_sort.cpp +++ b/test/test_insert_sort.cpp @@ -31,6 +31,10 @@ void test01 (void) 16, 6, 14, 21, 5, 1, 12, 19, 22, 25, 8}; std::less< unsigned > comp; + + // Insertion Sort sort an empty range + insert_sort (&A[ 0 ], &A[ 0 ], comp); + // Insertion Sort Unordered, not repeated insert_sort (&A[ 0 ], &A[ 22 ], comp); for (unsigned i = 0; i < 21; i++) { diff --git a/test/test_parallel_stable_sort.cpp b/test/test_parallel_stable_sort.cpp index 6c1dace..f790677 100644 --- a/test/test_parallel_stable_sort.cpp +++ b/test/test_parallel_stable_sort.cpp @@ -51,6 +51,10 @@ void test1() }; }; V3 = V2 = V1; + + // check to sort with 0 elements + bss::parallel_stable_sort(V1.end(), V1.end()); + bss::parallel_stable_sort(V1.begin(), V1.end()); std::stable_sort(V2.begin(), V2.end()); bss::parallel_stable_sort(V3.begin(), V3.end(), 0); diff --git a/test/test_sample_sort.cpp b/test/test_sample_sort.cpp index a83634f..c23b56f 100644 --- a/test/test_sample_sort.cpp +++ b/test/test_sample_sort.cpp @@ -50,6 +50,9 @@ void test1() }; }; V3 = V2 = V1; + // sort 0 elements + bss::sample_sort(V1.end(), V1.end()); + bss::sample_sort(V1.begin(), V1.end()); std::stable_sort(V2.begin(), V2.end()); bss::sample_sort(V3.begin(), V3.end(), 0); diff --git a/test/test_spinsort.cpp b/test/test_spinsort.cpp index b8e2f26..91b5a43 100644 --- a/test/test_spinsort.cpp +++ b/test/test_spinsort.cpp @@ -61,6 +61,10 @@ void test1 ( ) }; }; V2 = V1; + // test with 0 elements + spinsort (V1.end ( ), V1.end ( ), compare_t ( )); + + spinsort (V1.begin ( ), V1.end ( ), compare_t ( )); std::stable_sort (V2.begin ( ), V2.end ( )); From 07545798b65163b5334ba760e2fce042f2f0862f Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Tue, 29 Aug 2023 10:16:30 +0200 Subject: [PATCH 08/17] Add files via upload Check when the range to sort is empty --- include/boost/sort/flat_stable_sort/flat_stable_sort.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/sort/flat_stable_sort/flat_stable_sort.hpp b/include/boost/sort/flat_stable_sort/flat_stable_sort.hpp index 8ebfdfb..340b9ff 100644 --- a/include/boost/sort/flat_stable_sort/flat_stable_sort.hpp +++ b/include/boost/sort/flat_stable_sort/flat_stable_sort.hpp @@ -87,6 +87,9 @@ class flat_stable_sort: public bsc::merge_block circular_t *ptr_circ) : merge_block_t(first, last, comp, ptr_circ) { + auto nelem = last - first; + assert (nelem >= 0); + if (nelem < 2) return; divide(index.begin(), index.end()); rearrange_with_index(); }; From 646524556d7215698b7025eb7cca002799812b71 Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Tue, 5 Sep 2023 20:46:47 +1000 Subject: [PATCH 09/17] Fix typo in error message --- include/boost/sort/common/file_vector.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/sort/common/file_vector.hpp b/include/boost/sort/common/file_vector.hpp index ec2bb0e..642ccf3 100644 --- a/include/boost/sort/common/file_vector.hpp +++ b/include/boost/sort/common/file_vector.hpp @@ -89,7 +89,7 @@ inline int fill_vector_uint64(const std::string & filename, size_t uCount = length / 8; if (uCount < NElem) { - throw std::ios_base::failure("incorrect lenght of the file\n"); + throw std::ios_base::failure("incorrect length of the file\n"); }; V.clear(); V.reserve(NElem); From bf131a207ef6f2dbecdd40323ba946fb001ac192 Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Tue, 5 Sep 2023 20:50:50 +1000 Subject: [PATCH 10/17] Update macOS github workflow for macos-12 (Monterey) --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d2122a..368d074 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -144,12 +144,12 @@ jobs: - name: "TOOLSET=clang CXXSTD=03,11,14,1z Job 2" buildtype: "boost" packages: "" - os: "macos-10.15" + os: "macos-12" cxx: "clang++" sources: "" llvm_os: "" llvm_ver: "" - xcode_version: 11.7 + xcode_version: 14.2 toolset: "clang" cxxstd: "03,11,14,1z" From f24f82b8a8bec62ccf248b3b542787022eca1a4b Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Wed, 6 Sep 2023 17:31:36 +0200 Subject: [PATCH 11/17] correction of pedantic errors --- include/boost/sort/common/stack_cnc.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/sort/common/stack_cnc.hpp b/include/boost/sort/common/stack_cnc.hpp index e040b1d..ca2039f 100644 --- a/include/boost/sort/common/stack_cnc.hpp +++ b/include/boost/sort/common/stack_cnc.hpp @@ -99,7 +99,7 @@ class stack_cnc { std::lock_guard < spinlock_t > guard(spl); v_t.emplace_back(std::forward< Args > (args)...); - }; + } // //------------------------------------------------------------------------- @@ -116,7 +116,7 @@ class stack_cnc P = std::move(v_t.back()); v_t.pop_back(); return true; - }; + } //------------------------------------------------------------------------- // function : push_back /// @brief Insert one vector at the end of the container @@ -132,7 +132,7 @@ class stack_cnc v_t.push_back(v_other[i]); } return *this; - }; + } }; // end class stack_cnc From 29302315613f9e77e0daf40c0ab18d1767e64966 Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Wed, 6 Sep 2023 17:33:05 +0200 Subject: [PATCH 12/17] correction of errors showed with the pedantic option --- include/boost/sort/common/util/traits.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/sort/common/util/traits.hpp b/include/boost/sort/common/util/traits.hpp index 622a99c..d4237b8 100644 --- a/include/boost/sort/common/util/traits.hpp +++ b/include/boost/sort/common/util/traits.hpp @@ -112,7 +112,7 @@ struct constructor void operator()(Args && ... args) { T(std::forward (args) ...); - }; + } }; // //**************************************************************************** From 2fa0aca0bdfd19e8aba8f3d37291796eb3ce4efa Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Sun, 10 Sep 2023 21:52:12 +1000 Subject: [PATCH 13/17] Resolve Issue #64 - boost/sort/common/util/insert.hpp need not include itself --- include/boost/sort/common/util/insert.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/sort/common/util/insert.hpp b/include/boost/sort/common/util/insert.hpp index 485e25b..150ef26 100644 --- a/include/boost/sort/common/util/insert.hpp +++ b/include/boost/sort/common/util/insert.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include From 11099a22ec864fe135c803058cfecc030946462c Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Mon, 11 Sep 2023 16:17:41 +1000 Subject: [PATCH 14/17] pdqsort: Resolve MS compiler warnings about assigning size_t to unsigned char --- include/boost/sort/pdqsort/pdqsort.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/sort/pdqsort/pdqsort.hpp b/include/boost/sort/pdqsort/pdqsort.hpp index 8352e39..4a936d3 100644 --- a/include/boost/sort/pdqsort/pdqsort.hpp +++ b/include/boost/sort/pdqsort/pdqsort.hpp @@ -232,7 +232,7 @@ namespace pdqsort_detail { // Fill the offset blocks. if (left_split >= block_size) { - for (size_t i = 0; i < block_size;) { + for (unsigned char i = 0; i < static_cast(block_size);) { offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first; offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first; offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first; @@ -249,7 +249,7 @@ namespace pdqsort_detail { } if (right_split >= block_size) { - for (size_t i = 0; i < block_size;) { + for (unsigned char i = 0; i < static_cast(block_size);) { offsets_r[num_r] = ++i; num_r += comp(*--last, pivot); offsets_r[num_r] = ++i; num_r += comp(*--last, pivot); offsets_r[num_r] = ++i; num_r += comp(*--last, pivot); @@ -260,7 +260,7 @@ namespace pdqsort_detail { offsets_r[num_r] = ++i; num_r += comp(*--last, pivot); } } else { - for (size_t i = 0; i < right_split;) { + for (unsigned char i = 0; i < static_cast(right_split);) { offsets_r[num_r] = ++i; num_r += comp(*--last, pivot); } } From 5daa1d4f2471c6cb0f8a48ac5f2fe94b6216a377 Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Mon, 11 Sep 2023 16:43:34 +1000 Subject: [PATCH 15/17] pdqsort: Resolve MS compiler warnings about assigning size_t to unsigned char --- include/boost/sort/pdqsort/pdqsort.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/sort/pdqsort/pdqsort.hpp b/include/boost/sort/pdqsort/pdqsort.hpp index 4a936d3..fd447ce 100644 --- a/include/boost/sort/pdqsort/pdqsort.hpp +++ b/include/boost/sort/pdqsort/pdqsort.hpp @@ -243,7 +243,7 @@ namespace pdqsort_detail { offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first; } } else { - for (size_t i = 0; i < left_split;) { + for (unsigned char i = 0; i < static_cast(left_split);) { offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first; } } From a9e684e45f95f58f2d48a38ed75bd09794c13fd2 Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Wed, 13 Sep 2023 17:54:11 +0200 Subject: [PATCH 16/17] Add files via upload delete the #include sort.hpp and delete the function commneted --- .../boost/sort/insert_sort/insert_sort.hpp | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/include/boost/sort/insert_sort/insert_sort.hpp b/include/boost/sort/insert_sort/insert_sort.hpp index c03a96f..e7fe6f6 100644 --- a/include/boost/sort/insert_sort/insert_sort.hpp +++ b/include/boost/sort/insert_sort/insert_sort.hpp @@ -19,7 +19,6 @@ #include #include // std::swap #include -#include namespace boost { @@ -61,56 +60,6 @@ static void insert_sort (Iter_t first, Iter_t last, }; }; -/* -// -//----------------------------------------------------------------------------- -// function : insert_partial_sort -/// @brief : Insertion sort of elements sorted -/// @param first: iterator to the first element of the range -/// @param mid : last pointer of the sorted data, and first pointer to the -/// elements to insert -/// @param last : iterator to the next element of the last in the range -/// @param comp : object for to do the comparison between the elements -/// @remarks This algorithm is O(N^2) -//----------------------------------------------------------------------------- -template < class Iter_t, typename Compare = compare_iter < Iter_t > > -void insert_partial_sort (Iter_t first, Iter_t mid, Iter_t last, - Compare comp = Compare()) -{ - //-------------------------------------------------------------------- - // DEFINITIONS - //-------------------------------------------------------------------- - typedef value_iter< Iter_t > value_t; - - if ( mid == last ) return ; - insert_sort ( mid, last, comp); - if (first == mid) return ; - - // creation of the vector of elements to insert and their position in the - // sorted part - std::vector viter ; - std::vector vdata ; - - for ( Iter_t alpha = mid ; alpha != last ; ++alpha) - vdata.push_back ( std::move ( *alpha)); - - Iter_t linf = first , lsup = mid ; - for ( uint32_t i= 0 ; i < vdata.size() ; ++i) - { Iter_t it1 = std::upper_bound ( linf, lsup , vdata[i], comp); - viter.push_back ( it1 ); - linf = it1 ; - }; - - // moving the elements - viter.push_back ( mid) ; - for ( uint32_t i = viter.size() -1 ; i!= 0 ; --i) - { Iter_t src = viter[i], limit = viter[i-1]; - Iter_t dest = src + ( i); - while ( src != limit) * (--dest) = std::move ( *(--src)); - *(viter[i-1] + (i -1)) = std::move (vdata[i-1]); - }; -} -*/ // //**************************************************************************** }; // End namespace sort From e5393b78afc2fe8da4157c0ea91b654ec63b46b3 Mon Sep 17 00:00:00 2001 From: Francisco Tapia Date: Wed, 13 Sep 2023 17:55:56 +0200 Subject: [PATCH 17/17] Add files via upload delete dependencies of the insert.hpp file --- test/test_insert_sort.cpp | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/test/test_insert_sort.cpp b/test/test_insert_sort.cpp index 34e7785..4027edc 100644 --- a/test/test_insert_sort.cpp +++ b/test/test_insert_sort.cpp @@ -23,7 +23,6 @@ using namespace boost::sort; using namespace std; -using boost::sort::common::util::insert_sorted; void test01 (void) { @@ -121,47 +120,9 @@ void test02 (void) A[ 1001 + NELEM ] == 999999999); }; - -void test03 ( void) -{ - std::vector V {1,3,5,2,4}; - std::less comp ; - uint32_t aux[10] ; - - insert_sorted ( V.begin() , V.begin()+3, V.end(), comp, aux); - //insert_partial_sort ( V.begin() , V.begin()+3, V.end() , comp); - for ( uint32_t i =0 ; i < V.size() ; ++i) - std::cout<