45 for ( i = hi-4; i >= lo; i-- ) {
48 for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
54 for ( i = hi-1; i >= lo; i-- ) {
57 for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
65 #define fswap(zz1, zz2) \
66 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
68 #define fvswap(zzp1, zzp2, zzn) \
70 Int32 yyp1 = (zzp1); \
71 Int32 yyp2 = (zzp2); \
74 fswap(fmap[yyp1], fmap[yyp2]); \
75 yyp1++; yyp2++; yyn--; \
80 #define fmin(a,b) ((a) < (b)) ? (a) : (b)
82 #define fpush(lz,hz) { stackLo[sp] = lz; \
86 #define fpop(lz,hz) { sp--; \
90 #define FALLBACK_QSORT_SMALL_THRESH 10
91 #define FALLBACK_QSORT_STACK_SIZE 100
100 Int32 unLo, unHi, ltLo, gtHi, n, m;
109 fpush ( loSt, hiSt );
128 r = ((r * 7621) + 1) % 32768;
130 if (r3 == 0) med = eclass[fmap[lo]];
else
131 if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]];
else
132 med = eclass[fmap[hi]];
139 if (unLo > unHi)
break;
142 fswap(fmap[unLo], fmap[ltLo]);
150 if (unLo > unHi)
break;
153 fswap(fmap[unHi], fmap[gtHi]);
160 if (unLo > unHi)
break;
161 fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
164 AssertD ( unHi == unLo-1,
"fallbackQSort3(2)" );
166 if (gtHi < ltLo)
continue;
168 n =
fmin(ltLo-lo, unLo-ltLo);
fvswap(lo, unLo-n, n);
169 m =
fmin(hi-gtHi, gtHi-unHi);
fvswap(unLo, hi-m+1, m);
171 n = lo + unLo - ltLo - 1;
172 m = hi - (gtHi - unHi) + 1;
174 if (n - lo > hi - m) {
189 #undef FALLBACK_QSORT_SMALL_THRESH
190 #undef FALLBACK_QSORT_STACK_SIZE
207 #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
208 #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
209 #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
210 #define WORD_BH(zz) bhtab[(zz) >> 5]
211 #define UNALIGNED_BH(zz) ((zz) & 0x01f)
222 Int32 H, i, j, k, l, r, cc, cc1;
232 VPrintf0 (
" bucket sorting ...\n" );
233 for (i = 0; i < 257; i++) ftab[i] = 0;
234 for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
235 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
236 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
238 for (i = 0; i < nblock; i++) {
245 nBhtab = 2 + (nblock / 32);
246 for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
247 for (i = 0; i < 256; i++)
SET_BH(ftab[i]);
256 for (i = 0; i < 32; i++) {
269 for (i = 0; i < nblock; i++) {
271 k = fmap[i] - H;
if (k < 0) k += nblock;
283 while (
WORD_BH(k) == 0xffffffff) k += 32;
287 if (l >= nblock)
break;
290 while (
WORD_BH(k) == 0x00000000) k += 32;
294 if (r >= nblock)
break;
298 nNotDone += (r - l + 1);
303 for (i = l; i <= r; i++) {
304 cc1 = eclass[fmap[i]];
305 if (cc != cc1) {
SET_BH(i); cc = cc1; };
311 VPrintf1 (
"%6d unresolved strings\n", nNotDone );
314 if (H > nblock || nNotDone == 0)
break;
323 VPrintf0 (
" reconstructing block ...\n" );
325 for (i = 0; i < nblock; i++) {
326 while (ftabCopy[j] == 0) j++;
328 eclass8[fmap[i]] = (
UChar)j;
360 AssertD ( i1 != i2,
"mainGtU" );
362 c1 = block[i1]; c2 = block[i2];
363 if (c1 != c2)
return (c1 > c2);
366 c1 = block[i1]; c2 = block[i2];
367 if (c1 != c2)
return (c1 > c2);
370 c1 = block[i1]; c2 = block[i2];
371 if (c1 != c2)
return (c1 > c2);
374 c1 = block[i1]; c2 = block[i2];
375 if (c1 != c2)
return (c1 > c2);
378 c1 = block[i1]; c2 = block[i2];
379 if (c1 != c2)
return (c1 > c2);
382 c1 = block[i1]; c2 = block[i2];
383 if (c1 != c2)
return (c1 > c2);
386 c1 = block[i1]; c2 = block[i2];
387 if (c1 != c2)
return (c1 > c2);
390 c1 = block[i1]; c2 = block[i2];
391 if (c1 != c2)
return (c1 > c2);
394 c1 = block[i1]; c2 = block[i2];
395 if (c1 != c2)
return (c1 > c2);
398 c1 = block[i1]; c2 = block[i2];
399 if (c1 != c2)
return (c1 > c2);
402 c1 = block[i1]; c2 = block[i2];
403 if (c1 != c2)
return (c1 > c2);
406 c1 = block[i1]; c2 = block[i2];
407 if (c1 != c2)
return (c1 > c2);
414 c1 = block[i1]; c2 = block[i2];
415 if (c1 != c2)
return (c1 > c2);
416 s1 = quadrant[i1]; s2 = quadrant[i2];
417 if (s1 != s2)
return (s1 > s2);
420 c1 = block[i1]; c2 = block[i2];
421 if (c1 != c2)
return (c1 > c2);
422 s1 = quadrant[i1]; s2 = quadrant[i2];
423 if (s1 != s2)
return (s1 > s2);
426 c1 = block[i1]; c2 = block[i2];
427 if (c1 != c2)
return (c1 > c2);
428 s1 = quadrant[i1]; s2 = quadrant[i2];
429 if (s1 != s2)
return (s1 > s2);
432 c1 = block[i1]; c2 = block[i2];
433 if (c1 != c2)
return (c1 > c2);
434 s1 = quadrant[i1]; s2 = quadrant[i2];
435 if (s1 != s2)
return (s1 > s2);
438 c1 = block[i1]; c2 = block[i2];
439 if (c1 != c2)
return (c1 > c2);
440 s1 = quadrant[i1]; s2 = quadrant[i2];
441 if (s1 != s2)
return (s1 > s2);
444 c1 = block[i1]; c2 = block[i2];
445 if (c1 != c2)
return (c1 > c2);
446 s1 = quadrant[i1]; s2 = quadrant[i2];
447 if (s1 != s2)
return (s1 > s2);
450 c1 = block[i1]; c2 = block[i2];
451 if (c1 != c2)
return (c1 > c2);
452 s1 = quadrant[i1]; s2 = quadrant[i2];
453 if (s1 != s2)
return (s1 > s2);
456 c1 = block[i1]; c2 = block[i2];
457 if (c1 != c2)
return (c1 > c2);
458 s1 = quadrant[i1]; s2 = quadrant[i2];
459 if (s1 != s2)
return (s1 > s2);
462 if (i1 >= nblock) i1 -= nblock;
463 if (i2 >= nblock) i2 -= nblock;
483 9841, 29524, 88573, 265720,
496 Int32 i, j, h, bigN, hp;
500 if (bigN < 2)
return;
503 while (
incs[hp] < bigN) hp++;
506 for (; hp >= 0; hp--) {
517 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
521 if (j <= (lo + h - 1))
break;
531 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
535 if (j <= (lo + h - 1))
break;
545 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
549 if (j <= (lo + h - 1))
break;
554 if (*budget < 0)
return;
569 #define mswap(zz1, zz2) \
570 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
572 #define mvswap(zzp1, zzp2, zzn) \
574 Int32 yyp1 = (zzp1); \
575 Int32 yyp2 = (zzp2); \
578 mswap(ptr[yyp1], ptr[yyp2]); \
579 yyp1++; yyp2++; yyn--; \
588 if (a > b) { t = a; a = b; b = t; };
596 #define mmin(a,b) ((a) < (b)) ? (a) : (b)
598 #define mpush(lz,hz,dz) { stackLo[sp] = lz; \
603 #define mpop(lz,hz,dz) { sp--; \
609 #define mnextsize(az) (nextHi[az]-nextLo[az])
611 #define mnextswap(az,bz) \
613 tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
614 tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
615 tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
618 #define MAIN_QSORT_SMALL_THRESH 20
619 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
620 #define MAIN_QSORT_STACK_SIZE 100
632 Int32 unLo, unHi, ltLo, gtHi, n, m, med;
644 mpush ( loSt, hiSt, dSt );
653 mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
654 if (*budget < 0)
return;
659 mmed3 ( block[ptr[ lo ]+d],
661 block[ptr[ (lo+hi)>>1 ]+d] );
668 if (unLo > unHi)
break;
669 n = ((
Int32)block[ptr[unLo]+d]) - med;
671 mswap(ptr[unLo], ptr[ltLo]);
672 ltLo++; unLo++;
continue;
678 if (unLo > unHi)
break;
679 n = ((
Int32)block[ptr[unHi]+d]) - med;
681 mswap(ptr[unHi], ptr[gtHi]);
682 gtHi--; unHi--;
continue;
687 if (unLo > unHi)
break;
688 mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
691 AssertD ( unHi == unLo-1,
"mainQSort3(2)" );
698 n =
mmin(ltLo-lo, unLo-ltLo);
mvswap(lo, unLo-n, n);
699 m =
mmin(hi-gtHi, gtHi-unHi);
mvswap(unLo, hi-m+1, m);
701 n = lo + unLo - ltLo - 1;
702 m = hi - (gtHi - unHi) + 1;
704 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
705 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
706 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
715 mpush (nextLo[0], nextHi[0], nextD[0]);
716 mpush (nextLo[1], nextHi[1], nextD[1]);
717 mpush (nextLo[2], nextHi[2], nextD[2]);
728 #undef MAIN_QSORT_SMALL_THRESH
729 #undef MAIN_QSORT_DEPTH_THRESH
730 #undef MAIN_QSORT_STACK_SIZE
748 #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
749 #define SETMASK (1 << 21)
750 #define CLEARMASK (~(SETMASK))
761 Int32 i, j, k, ss, sb;
762 Int32 runningOrder[256];
764 Int32 copyStart[256];
769 if (verb >= 4)
VPrintf0 (
" main sort initialise ...\n" );
772 for (i = 65536; i >= 0; i--) ftab[i] = 0;
776 for (; i >= 3; i -= 4) {
778 j = (j >> 8) | ( ((
UInt16)block[i]) << 8);
781 j = (j >> 8) | ( ((
UInt16)block[i-1]) << 8);
784 j = (j >> 8) | ( ((
UInt16)block[i-2]) << 8);
787 j = (j >> 8) | ( ((
UInt16)block[i-3]) << 8);
790 for (; i >= 0; i--) {
792 j = (j >> 8) | ( ((
UInt16)block[i]) << 8);
798 block [nblock+i] = block[i];
799 quadrant[nblock+i] = 0;
802 if (verb >= 4)
VPrintf0 (
" bucket sorting ...\n" );
805 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
809 for (; i >= 3; i -= 4) {
810 s = (s >> 8) | (block[i] << 8);
814 s = (s >> 8) | (block[i-1] << 8);
818 s = (s >> 8) | (block[i-2] << 8);
822 s = (s >> 8) | (block[i-3] << 8);
827 for (; i >= 0; i--) {
828 s = (s >> 8) | (block[i] << 8);
839 for (i = 0; i <= 255; i++) {
847 do h = 3 * h + 1;
while (h <= 256);
850 for (i = h; i <= 255; i++) {
851 vv = runningOrder[i];
854 runningOrder[j] = runningOrder[j-h];
856 if (j <= (h - 1))
goto zero;
859 runningOrder[j] = vv;
870 for (i = 0; i <= 255; i++) {
878 ss = runningOrder[i];
888 for (j = 0; j <= 255; j++) {
891 if ( ! (ftab[sb] &
SETMASK) ) {
898 ss, j, numQSorted, hi - lo + 1 );
900 ptr, block, quadrant, nblock,
903 numQSorted += (hi - lo + 1);
904 if (*budget < 0)
return;
911 AssertH ( !bigDone[ss], 1006 );
921 for (j = 0; j <= 255; j++) {
922 copyStart[j] = ftab[(j << 8) + ss] &
CLEARMASK;
923 copyEnd [j] = (ftab[(j << 8) + ss + 1] &
CLEARMASK) - 1;
925 for (j = ftab[ss << 8] &
CLEARMASK; j < copyStart[ss]; j++) {
926 k = ptr[j]-1;
if (k < 0) k += nblock;
929 ptr[ copyStart[c1]++ ] = k;
931 for (j = (ftab[(ss+1) << 8] &
CLEARMASK) - 1; j > copyEnd[ss]; j--) {
932 k = ptr[j]-1;
if (k < 0) k += nblock;
935 ptr[ copyEnd[c1]-- ] = k;
939 AssertH ( (copyStart[ss]-1 == copyEnd[ss])
945 (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
948 for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |=
SETMASK;
993 Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
996 while ((bbSize >> shifts) > 65534) shifts++;
998 for (j = bbSize-1; j >= 0; j--) {
999 Int32 a2update = ptr[bbStart + j];
1001 quadrant[a2update] = qVal;
1002 if (a2update < BZ_N_OVERSHOOT)
1003 quadrant[a2update + nblock] = qVal;
1005 AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
1011 VPrintf3 (
" %d pointers, %d sorted, %d scanned\n",
1012 nblock, numQSorted, nblock - numQSorted );
1046 if (nblock < 10000) {
1056 quadrant = (
UInt16*)(&(block[i]));
1065 if (wfact < 1 ) wfact = 1;
1066 if (wfact > 100) wfact = 100;
1067 budgetInit = nblock * ((wfact-1) / 3);
1068 budget = budgetInit;
1070 mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
1072 VPrintf3 (
" %d work, %d block, ratio %5.2f\n",
1073 budgetInit - budget,
1075 (
float)(budgetInit - budget) /
1076 (
float)(nblock==0 ? 1 : nblock) );
1079 VPrintf0 (
" too repetitive; using fallback"
1080 " sorting algorithm\n" );
1086 for (i = 0; i < s->
nblock; i++)
#define FALLBACK_QSORT_STACK_SIZE
#define VPrintf1(zf, za1)
static ABC_NAMESPACE_IMPL_START __inline__ void fallbackSimpleSort(UInt32 *fmap, UInt32 *eclass, Int32 lo, Int32 hi)
#define MAIN_QSORT_SMALL_THRESH
#define AssertH(cond, errcode)
#define mnextswap(az, bz)
static __inline__ UChar mmed3(UChar a, UChar b, UChar c)
void BZ2_blockSort(EState *s)
#define mvswap(zzp1, zzp2, zzn)
static void mainSimpleSort(UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 lo, Int32 hi, Int32 d, Int32 *budget)
#define ABC_NAMESPACE_IMPL_END
static char s1[largest_string]
#define fvswap(zzp1, zzp2, zzn)
#define FALLBACK_QSORT_SMALL_THRESH
#define ABC_NAMESPACE_IMPL_START
#define MAIN_QSORT_DEPTH_THRESH
#define VPrintf3(zf, za1, za2, za3)
static void fallbackSort(UInt32 *fmap, UInt32 *eclass, UInt32 *bhtab, Int32 nblock, Int32 verb)
#define mpush(lz, hz, dz)
#define AssertD(cond, msg)
static void fallbackQSort3(UInt32 *fmap, UInt32 *eclass, Int32 loSt, Int32 hiSt)
#define MAIN_QSORT_STACK_SIZE
#define VPrintf4(zf, za1, za2, za3, za4)
static void mainQSort3(UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 loSt, Int32 hiSt, Int32 dSt, Int32 *budget)
static __inline__ Bool mainGtU(UInt32 i1, UInt32 i2, UChar *block, UInt16 *quadrant, UInt32 nblock, Int32 *budget)
static void mainSort(UInt32 *ptr, UChar *block, UInt16 *quadrant, UInt32 *ftab, Int32 nblock, Int32 verb, Int32 *budget)