00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_parallel_sort_H
00022 #define __TBB_parallel_sort_H
00023
00024 #include "parallel_for.h"
00025 #include <algorithm>
00026 #include <iterator>
00027 #include <functional>
00028
00029 namespace tbb {
00030
00032 namespace internal {
00033
00035
00038 template<typename RandomAccessIterator, typename Compare>
00039 struct quick_sort_range: private no_assign {
00040 static const size_t grainsize = 500;
00041 const Compare ∁
00042 RandomAccessIterator begin;
00043 size_t size;
00044
00045 quick_sort_range( RandomAccessIterator begin_, size_t size_, const Compare &comp_ ) :
00046 comp(comp_), begin(begin_), size(size_) {}
00047
00048 bool empty() const {return size==0;}
00049 bool is_divisible() const {return size>=grainsize;}
00050
00051 quick_sort_range( quick_sort_range& range, split ) : comp(range.comp) {
00052 RandomAccessIterator array = range.begin;
00053 RandomAccessIterator key0 = range.begin;
00054 size_t m = range.size/2u;
00055 std::swap ( array[0], array[m] );
00056
00057 size_t i=0;
00058 size_t j=range.size;
00059
00060 for(;;) {
00061 __TBB_ASSERT( i<j, NULL );
00062
00063 do {
00064 --j;
00065 __TBB_ASSERT( i<=j, "bad ordering relation?" );
00066 } while( comp( *key0, array[j] ));
00067 do {
00068 __TBB_ASSERT( i<=j, NULL );
00069 if( i==j ) goto partition;
00070 ++i;
00071 } while( comp( array[i],*key0 ));
00072 if( i==j ) goto partition;
00073 std::swap( array[i], array[j] );
00074 }
00075 partition:
00076
00077 std::swap( array[j], *key0 );
00078
00079
00080
00081 i=j+1;
00082 begin = array+i;
00083 size = range.size-i;
00084 range.size = j;
00085 }
00086 };
00087
00089
00090 template<typename RandomAccessIterator, typename Compare>
00091 struct quick_sort_body {
00092 void operator()( const quick_sort_range<RandomAccessIterator,Compare>& range ) const {
00093
00094 std::sort( range.begin, range.begin + range.size, range.comp );
00095 }
00096 };
00097
00099
00100 template<typename RandomAccessIterator, typename Compare>
00101 void parallel_quick_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp ) {
00102 parallel_for( quick_sort_range<RandomAccessIterator,Compare>(begin, end-begin, comp ), quick_sort_body<RandomAccessIterator,Compare>() );
00103 }
00104
00105 }
00107
00118
00120
00123 template<typename RandomAccessIterator, typename Compare>
00124 void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp) {
00125 const int min_parallel_size = 500;
00126 if( end > begin ) {
00127 if (end - begin < min_parallel_size) {
00128 std::sort(begin, end, comp);
00129 } else {
00130 internal::parallel_quick_sort(begin, end, comp);
00131 }
00132 }
00133 }
00134
00136
00137 template<typename RandomAccessIterator>
00138 inline void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end ) {
00139 parallel_sort( begin, end, std::less< typename std::iterator_traits<RandomAccessIterator>::value_type >() );
00140 }
00141
00143
00144 template<typename T>
00145 inline void parallel_sort( T * begin, T * end ) {
00146 parallel_sort( begin, end, std::less< T >() );
00147 }
00149
00150
00151 }
00152
00153 #endif
00154