22 #define mDoSort(extra_var,extra_action,sztype) \
25 for ( sztype d=sz/2; d>0; d=d/2 ) \
26 for ( sztype i=d; i<sz; i++ ) \
27 for ( sztype j=i-d; j>=0 && arr[j]>arr[j+d]; j-=d ) \
29 tmp = arr[j]; arr[j] = arr[j+d]; arr[j+d] = tmp; \
35 template <
class T,
class I>
40 template <
class T,
class IT,
class I>
42 mDoSort(IT itmp,itmp = idxs[j]; idxs[j] = idxs[j+d]; idxs[j+d] = itmp,I)
45 #define
mDoSort(extra_var,extra_action,sztype) \
48 for ( sztype d=sz/2; d>0; d=d/2 ) \
49 for ( sztype i=d; i<sz; i++ ) \
50 for ( sztype j=i-d; j>=0 && arr[j]>arr[j+d]; j-=d ) \
52 Swap( arr[j], arr[j+d] ); \
63 template <
class T,
class IT>
65 mDoSort(IT itmp,itmp = idxs[j]; idxs[j] = idxs[j+d]; idxs[j+d] = itmp,int)
70 template <class T,class I>
75 for ( I idx=0; idx<sz; ++idx )
77 const int vidx = vals.indexOf( arr[idx] );
80 if ( vals.size()>maxnrvals )
92 const int vsize =
mCast(
int,vals.size());
94 for (
int idx=0; idx<vsize; idx++ )
99 for (
int idx=0; idx<vsize; ++idx )
101 for (
int idy=count[idxs[idx]]-1; idy>=0; --idy )
102 arr[++index] = vals[idx];
135 static bool mergeLists(
const T* vals, T* res,
136 idx_type start0,idx_type start1,
137 idx_type start2,idx_type stop,
138 size_type& totalsz );
169 const int localseed = (partsortglobalseed *
FA +
FC) %
FM;
175 partsortglobalseed = localseed;
177 return (
float) localseed;
181 template <
class T,
class I>
inline
183 I* jstart, I* jstop )
185 I ipivot, ileft, iright;
190 ipivot = istart + (istop-istart) * (
float)localseed / (float)
FM + .5;
191 if ( ipivot < istart ) ipivot = istart;
192 if ( ipivot > istop ) ipivot = istop;
193 pivotval = arr[ipivot];
195 for ( ileft=istart, iright=istop; ; )
197 while ( arr[ileft] <=pivotval && ileft<istop ) ileft++;
198 while ( arr[iright]>=pivotval && iright>istart ) iright--;
199 if ( ileft < iright )
202 arr[ileft++] = arr[iright];
208 if ( ileft < ipivot )
211 arr[ileft++] = arr[ipivot];
214 else if ( ipivot < iright )
217 arr[iright--] = arr[ipivot];
226 template <
class T,
class I>
inline
232 for ( i=istart+1; i<=istop; i++ )
234 for ( arr_i=arr[i],j=i; j>istart && arr[j-1]>arr_i; j-- )
241 template <
class T,
class I>
inline
247 I j, k, p = 0, q = sz-1;
253 if ( itarget <= j ) q = j;
254 else if ( itarget >= k ) p = k;
262 template <
class T,
class I>
inline
269 qstack[top++] = sz - 1;
298 template <
class T,
class IT>
inline
308 ipivot = istart + (istop-istart) * (
float)localseed / (float)
FM;
309 if ( ipivot < istart ) ipivot = istart;
310 if ( ipivot > istop ) ipivot = istop;
311 pivotval = arr[ipivot];
313 for ( ileft=istart, iright=istop; ; )
315 while ( arr[ileft] <=pivotval && ileft<istop ) ileft++;
316 while ( arr[iright]>=pivotval && iright>istart ) iright--;
317 if ( ileft < iright )
322 iarr[ileft] = iarr[iright];
323 arr[ileft++] = arr[iright];
331 if ( ileft < ipivot )
336 iarr[ileft] = iarr[ipivot];
337 arr[ileft++] = arr[ipivot];
342 else if ( ipivot < iright )
347 iarr[iright] = iarr[ipivot];
348 arr[iright--] = arr[ipivot];
359 template <
class T,
class IT>
inline
366 for ( i=istart+1; i<=istop; i++ )
368 for ( iarr_i=iarr[i],arr_i=arr[i],j=i; j>istart && arr[j-1]>arr_i; j-- )
379 template <
class T,
class IT>
386 partSort( arr, iarr, p, q, &j, &k );
388 if ( itarget <= j ) q = j;
389 else if ( itarget >= k ) p = k;
397 template <
class T,
class IT>
inline
403 qstack[top++] = sz - 1;
412 partSort( arr, iarr, p, q, &j, &k );
440 template <
class T>
inline
445 , barrier_( -1, false )
453 template <
class T>
inline
459 , barrier_( -1, false )
466 template <
class T>
inline
472 barrier_.setNrThreads( nrthreads );
484 totalnr_ = (1+nrmerges)*nrvals_;
489 template <
class T>
inline
495 if ( curvals_!=vals_ )
496 OD::memCopy( vals_, curvals_, nrvals_*
sizeof(T) );
502 template <
class T>
inline
505 const od_int64 threadsize = stop-start+1;
506 if ( threadsize<100 )
516 quickSort( vals_+start, idxs_+start, threadsize );
521 if ( !shouldContinue() )
524 addToNrDone( threadsize );
526 barrier_.mutex().lock();
528 barrier_.mutex().unLock();
532 if ( barrier_.waitForAll(
false) )
534 if ( curvals_==vals_ )
536 curvals_ = tmpbuffer_;
545 starts_ = newstarts_;
546 barrier_.setNrThreads( starts_.size()/2 );
547 barrier_.releaseAllNoLock();
550 if ( thread>=barrier_.nrThreads() )
552 barrier_.mutex().unLock();
557 const idx_type curstart0 = starts_[0]; starts_.removeSingle( 0 );
558 const idx_type curstart1 = starts_[0]; starts_.removeSingle( 0 );
560 if ( starts_.size()==1 )
562 curstart2 = starts_[0];
563 starts_.removeSingle( 0 );
568 const idx_type curstop = (starts_.size() ? starts_[0] : nrvals_)-1;
569 newstarts_ += curstart0;
570 barrier_.mutex().unLock();
573 if ( !mergeLists( curvals_, buf_,
574 curstart0, curstart1, curstart2, curstop, cursize) )
577 if ( !shouldContinue() )
580 addToNrDone( cursize );
587 template <
class T>
inline
594 const size_type sz1 = start2==-1 ? stop-start1+1 : start2-start1;
595 const size_type sz2 = start2==-1 ? 0 : stop-start2+1;
596 totalsz = sz0+sz1+sz2;
598 const T* ptr0 = valptr + start0;
599 const T* stopptr0 = ptr0+sz0;
600 const T* ptr1 = valptr + start1;
601 const T* stopptr1 = ptr1+sz1;
602 const T* ptr2 = start2==-1 ? 0 : valptr + start2;
603 const T* stopptr2 = ptr2+sz2;
607 if ( ptr0 && (!ptr1 || *ptr0<*ptr1) && (!ptr2 || *ptr0<*ptr2 ) )
609 (*result++) = (*ptr0++);
610 if ( ptr0==stopptr0 )
613 else if ( ptr1 && ( !ptr2 || *ptr1<*ptr2 ) )
615 (*result++) = (*ptr1++);
616 if ( ptr1==stopptr1 )
621 (*result++) = (*ptr2++);
622 if ( ptr2==stopptr2 )