2 * bzip2 is written by Julian Seward <jseward@bzip.org>.
3 * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
4 * See README and LICENSE files in this directory for more information.
7 /*-------------------------------------------------------------*/
8 /*--- Block sorting machinery ---*/
9 /*--- blocksort.c ---*/
10 /*-------------------------------------------------------------*/
12 /* ------------------------------------------------------------------
13 This file is part of bzip2/libbzip2, a program and library for
14 lossless, block-sorting data compression.
16 bzip2/libbzip2 version 1.0.4 of 20 December 2006
17 Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
19 Please read the WARNING, DISCLAIMER and PATENTS sections in the
22 This program is released under the terms of the license contained
24 ------------------------------------------------------------------ */
26 /* #include "bzlib_private.h" */
28 /*---------------------------------------------*/
29 /*--- Fallback O(N log(N)^2) sorting ---*/
30 /*--- algorithm, for repetitive blocks ---*/
31 /*---------------------------------------------*/
33 /*---------------------------------------------*/
36 void fallbackSimpleSort(uint32_t* fmap,
47 for (i = hi-4; i >= lo; i--) {
50 for (j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4)
56 for (i = hi-1; i >= lo; i--) {
59 for (j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++)
66 /*---------------------------------------------*/
67 #define fswap(zz1, zz2) \
69 int32_t zztmp = zz1; \
74 #define fvswap(zzp1, zzp2, zzn) \
76 int32_t yyp1 = (zzp1); \
77 int32_t yyp2 = (zzp2); \
78 int32_t yyn = (zzn); \
80 fswap(fmap[yyp1], fmap[yyp2]); \
88 #define fmin(a,b) ((a) < (b)) ? (a) : (b)
90 #define fpush(lz,hz) { \
96 #define fpop(lz,hz) { \
102 #define FALLBACK_QSORT_SMALL_THRESH 10
103 #define FALLBACK_QSORT_STACK_SIZE 100
107 void fallbackQSort3(uint32_t* fmap,
112 int32_t unLo, unHi, ltLo, gtHi, n, m;
115 int32_t stackLo[FALLBACK_QSORT_STACK_SIZE];
116 int32_t stackHi[FALLBACK_QSORT_STACK_SIZE];
124 AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004);
127 if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
128 fallbackSimpleSort(fmap, eclass, lo, hi);
132 /* Random partitioning. Median of 3 sometimes fails to
133 * avoid bad cases. Median of 9 seems to help but
134 * looks rather expensive. This too seems to work but
135 * is cheaper. Guidance for the magic constants
136 * 7621 and 32768 is taken from Sedgewick's algorithms
139 r = ((r * 7621) + 1) % 32768;
142 med = eclass[fmap[lo]];
144 med = eclass[fmap[(lo+hi)>>1]];
146 med = eclass[fmap[hi]];
153 if (unLo > unHi) break;
154 n = (int32_t)eclass[fmap[unLo]] - (int32_t)med;
156 fswap(fmap[unLo], fmap[ltLo]);
165 if (unLo > unHi) break;
166 n = (int32_t)eclass[fmap[unHi]] - (int32_t)med;
168 fswap(fmap[unHi], fmap[gtHi]);
175 if (unLo > unHi) break;
176 fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
179 AssertD(unHi == unLo-1, "fallbackQSort3(2)");
181 if (gtHi < ltLo) continue;
183 n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
184 m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
186 n = lo + unLo - ltLo - 1;
187 m = hi - (gtHi - unHi) + 1;
189 if (n - lo > hi - m) {
204 #undef FALLBACK_QSORT_SMALL_THRESH
205 #undef FALLBACK_QSORT_STACK_SIZE
208 /*---------------------------------------------*/
211 * eclass exists for [0 .. nblock-1]
212 * ((UChar*)eclass) [0 .. nblock-1] holds block
213 * ptr exists for [0 .. nblock-1]
216 * ((UChar*)eclass) [0 .. nblock-1] holds block
217 * All other areas of eclass destroyed
218 * fmap [0 .. nblock-1] holds sorted order
219 * bhtab[0 .. 2+(nblock/32)] destroyed
222 #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
223 #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
224 #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
225 #define WORD_BH(zz) bhtab[(zz) >> 5]
226 #define UNALIGNED_BH(zz) ((zz) & 0x01f)
229 void fallbackSort(uint32_t* fmap,
235 int32_t ftabCopy[256];
236 int32_t H, i, j, k, l, r, cc, cc1;
239 UChar* eclass8 = (UChar*)eclass;
242 * Initial 1-char radix sort to generate
243 * initial fmap and initial BH bits.
245 for (i = 0; i < 257; i++) ftab[i] = 0;
246 for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
247 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
248 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
250 for (i = 0; i < nblock; i++) {
257 nBhtab = 2 + (nblock / 32);
258 for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
259 for (i = 0; i < 256; i++) SET_BH(ftab[i]);
262 * Inductively refine the buckets. Kind-of an
263 * "exponential radix sort" (!), inspired by the
264 * Manber-Myers suffix array construction algorithm.
267 /*-- set sentinel bits for block-end detection --*/
268 for (i = 0; i < 32; i++) {
269 SET_BH(nblock + 2*i);
270 CLEAR_BH(nblock + 2*i + 1);
273 /*-- the log(N) loop --*/
277 for (i = 0; i < nblock; i++) {
290 /*-- find the next non-singleton bucket --*/
292 while (ISSET_BH(k) && UNALIGNED_BH(k))
295 while (WORD_BH(k) == 0xffffffff) k += 32;
296 while (ISSET_BH(k)) k++;
301 while (!ISSET_BH(k) && UNALIGNED_BH(k))
304 while (WORD_BH(k) == 0x00000000) k += 32;
305 while (!ISSET_BH(k)) k++;
311 /*-- now [l, r] bracket current bucket --*/
313 nNotDone += (r - l + 1);
314 fallbackQSort3(fmap, eclass, l, r);
316 /*-- scan bucket and generate header bits-- */
318 for (i = l; i <= r; i++) {
319 cc1 = eclass[fmap[i]];
329 if (H > nblock || nNotDone == 0)
334 * Reconstruct the original block in
335 * eclass8 [0 .. nblock-1], since the
336 * previous phase destroyed it.
339 for (i = 0; i < nblock; i++) {
340 while (ftabCopy[j] == 0)
343 eclass8[fmap[i]] = (UChar)j;
345 AssertH(j < 256, 1005);
355 /*---------------------------------------------*/
356 /*--- The main, O(N^2 log(N)) sorting ---*/
357 /*--- algorithm. Faster for "normal" ---*/
358 /*--- non-repetitive blocks. ---*/
359 /*---------------------------------------------*/
361 /*---------------------------------------------*/
377 AssertD(i1 != i2, "mainGtU");
379 c1 = block[i1]; c2 = block[i2];
380 if (c1 != c2) return (c1 > c2);
383 c1 = block[i1]; c2 = block[i2];
384 if (c1 != c2) return (c1 > c2);
387 c1 = block[i1]; c2 = block[i2];
388 if (c1 != c2) return (c1 > c2);
391 c1 = block[i1]; c2 = block[i2];
392 if (c1 != c2) return (c1 > c2);
395 c1 = block[i1]; c2 = block[i2];
396 if (c1 != c2) return (c1 > c2);
399 c1 = block[i1]; c2 = block[i2];
400 if (c1 != c2) return (c1 > c2);
403 c1 = block[i1]; c2 = block[i2];
404 if (c1 != c2) return (c1 > c2);
407 c1 = block[i1]; c2 = block[i2];
408 if (c1 != c2) return (c1 > c2);
411 c1 = block[i1]; c2 = block[i2];
412 if (c1 != c2) return (c1 > c2);
415 c1 = block[i1]; c2 = block[i2];
416 if (c1 != c2) return (c1 > c2);
419 c1 = block[i1]; c2 = block[i2];
420 if (c1 != c2) return (c1 > c2);
423 c1 = block[i1]; c2 = block[i2];
424 if (c1 != c2) return (c1 > c2);
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 c1 = block[i1]; c2 = block[i2];
463 if (c1 != c2) return (c1 > c2);
464 s1 = quadrant[i1]; s2 = quadrant[i2];
465 if (s1 != s2) return (s1 > s2);
468 c1 = block[i1]; c2 = block[i2];
469 if (c1 != c2) return (c1 > c2);
470 s1 = quadrant[i1]; s2 = quadrant[i2];
471 if (s1 != s2) return (s1 > s2);
474 c1 = block[i1]; c2 = block[i2];
475 if (c1 != c2) return (c1 > c2);
476 s1 = quadrant[i1]; s2 = quadrant[i2];
477 if (s1 != s2) return (s1 > s2);
480 if (i1 >= nblock) i1 -= nblock;
481 if (i2 >= nblock) i2 -= nblock;
491 /*---------------------------------------------*/
493 * Knuth's increments seem to work better
494 * than Incerpi-Sedgewick here. Possibly
495 * because the number of elems to sort is
496 * usually small, typically <= 20.
499 const int32_t incs[14] = {
500 1, 4, 13, 40, 121, 364, 1093, 3280,
501 9841, 29524, 88573, 265720,
506 void mainSimpleSort(uint32_t* ptr,
515 int32_t i, j, h, bigN, hp;
519 if (bigN < 2) return;
522 while (incs[hp] < bigN) hp++;
525 for (; hp >= 0; hp--) {
536 while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
539 if (j <= (lo + h - 1)) break;
548 while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
551 if (j <= (lo + h - 1)) break;
560 while (mainGtU (ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
563 if (j <= (lo + h - 1)) break;
568 if (*budget < 0) return;
574 /*---------------------------------------------*/
576 * The following is an implementation of
577 * an elegant 3-way quicksort for strings,
578 * described in a paper "Fast Algorithms for
579 * Sorting and Searching Strings", by Robert
580 * Sedgewick and Jon L. Bentley.
583 #define mswap(zz1, zz2) \
585 int32_t zztmp = zz1; \
590 #define mvswap(zzp1, zzp2, zzn) \
592 int32_t yyp1 = (zzp1); \
593 int32_t yyp2 = (zzp2); \
594 int32_t yyn = (zzn); \
596 mswap(ptr[yyp1], ptr[yyp2]); \
605 UChar mmed3(UChar a, UChar b, UChar c)
621 #define mmin(a,b) ((a) < (b)) ? (a) : (b)
623 #define mpush(lz,hz,dz) \
631 #define mpop(lz,hz,dz) \
640 #define mnextsize(az) (nextHi[az]-nextLo[az])
642 #define mnextswap(az,bz) \
645 tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
646 tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
647 tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; \
650 #define MAIN_QSORT_SMALL_THRESH 20
651 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
652 #define MAIN_QSORT_STACK_SIZE 100
655 void mainQSort3(uint32_t* ptr,
664 int32_t unLo, unHi, ltLo, gtHi, n, m, med;
665 int32_t sp, lo, hi, d;
667 int32_t stackLo[MAIN_QSORT_STACK_SIZE];
668 int32_t stackHi[MAIN_QSORT_STACK_SIZE];
669 int32_t stackD [MAIN_QSORT_STACK_SIZE];
676 mpush(loSt, hiSt, dSt);
679 AssertH(sp < MAIN_QSORT_STACK_SIZE - 2, 1001);
682 if (hi - lo < MAIN_QSORT_SMALL_THRESH
683 || d > MAIN_QSORT_DEPTH_THRESH
685 mainSimpleSort(ptr, block, quadrant, nblock, lo, hi, d, budget);
691 med = (int32_t) mmed3(block[ptr[lo ] + d],
693 block[ptr[(lo+hi) >> 1] + d]);
702 n = ((int32_t)block[ptr[unLo]+d]) - med;
704 mswap(ptr[unLo], ptr[ltLo]);
715 n = ((int32_t)block[ptr[unHi]+d]) - med;
717 mswap(ptr[unHi], ptr[gtHi]);
727 mswap(ptr[unLo], ptr[unHi]);
732 AssertD(unHi == unLo-1, "mainQSort3(2)");
735 mpush(lo, hi, d + 1);
739 n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
740 m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
742 n = lo + unLo - ltLo - 1;
743 m = hi - (gtHi - unHi) + 1;
745 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
746 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
747 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
749 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
750 if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
751 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
753 AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)");
754 AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)");
756 mpush (nextLo[0], nextHi[0], nextD[0]);
757 mpush (nextLo[1], nextHi[1], nextD[1]);
758 mpush (nextLo[2], nextHi[2], nextD[2]);
769 #undef MAIN_QSORT_SMALL_THRESH
770 #undef MAIN_QSORT_DEPTH_THRESH
771 #undef MAIN_QSORT_STACK_SIZE
774 /*---------------------------------------------*/
776 * nblock > N_OVERSHOOT
777 * block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
778 * ((UChar*)block32) [0 .. nblock-1] holds block
779 * ptr exists for [0 .. nblock-1]
782 * ((UChar*)block32) [0 .. nblock-1] holds block
783 * All other areas of block32 destroyed
784 * ftab[0 .. 65536] destroyed
785 * ptr [0 .. nblock-1] holds sorted order
786 * if (*budget < 0), sorting was abandoned
789 #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
790 #define SETMASK (1 << 21)
791 #define CLEARMASK (~(SETMASK))
794 void mainSort(uint32_t* ptr,
801 int32_t i, j, k, ss, sb;
802 int32_t runningOrder[256];
804 int32_t copyStart[256];
805 int32_t copyEnd [256];
810 /*-- set up the 2-byte frequency table --*/
811 /* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */
812 memset(ftab, 0, 65537 * sizeof(ftab[0]));
817 for (; i >= 3; i -= 4) {
819 j = (j >> 8) |(((uint16_t)block[i]) << 8);
822 j = (j >> 8) |(((uint16_t)block[i-1]) << 8);
825 j = (j >> 8) |(((uint16_t)block[i-2]) << 8);
828 j = (j >> 8) |(((uint16_t)block[i-3]) << 8);
832 for (; i >= 0; i--) {
834 j = (j >> 8) |(((uint16_t)block[i]) << 8);
838 /*-- (emphasises close relationship of block & quadrant) --*/
839 for (i = 0; i < BZ_N_OVERSHOOT; i++) {
840 block [nblock+i] = block[i];
841 quadrant[nblock+i] = 0;
844 /*-- Complete the initial radix sort --*/
845 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
850 for (; i >= 3; i -= 4) {
851 s = (s >> 8) | (block[i] << 8);
855 s = (s >> 8) | (block[i-1] << 8);
859 s = (s >> 8) | (block[i-2] << 8);
863 s = (s >> 8) | (block[i-3] << 8);
869 for (; i >= 0; i--) {
870 s = (s >> 8) | (block[i] << 8);
877 * Now ftab contains the first loc of every small bucket.
878 * Calculate the running order, from smallest to largest
881 for (i = 0; i <= 255; i++) {
888 /* was: int32_t h = 1; */
889 /* do h = 3 * h + 1; while (h <= 256); */
894 for (i = h; i <= 255; i++) {
895 vv = runningOrder[i];
897 while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) {
898 runningOrder[j] = runningOrder[j-h];
900 if (j <= (h - 1)) goto zero;
903 runningOrder[j] = vv;
909 * The main sorting loop.
914 for (i = 0; i <= 255; i++) {
917 * Process big buckets, starting with the least full.
918 * Basically this is a 3-step process in which we call
919 * mainQSort3 to sort the small buckets [ss, j], but
920 * also make a big effort to avoid the calls if we can.
922 ss = runningOrder[i];
926 * Complete the big bucket [ss] by quicksorting
927 * any unsorted small buckets [ss, j], for j != ss.
928 * Hopefully previous pointer-scanning phases have already
929 * completed many of the small buckets [ss, j], so
930 * we don't have to sort them at all.
932 for (j = 0; j <= 255; j++) {
935 if (!(ftab[sb] & SETMASK)) {
936 int32_t lo = ftab[sb] & CLEARMASK;
937 int32_t hi = (ftab[sb+1] & CLEARMASK) - 1;
940 ptr, block, quadrant, nblock,
941 lo, hi, BZ_N_RADIX, budget
943 numQSorted += (hi - lo + 1);
944 if (*budget < 0) return;
951 AssertH(!bigDone[ss], 1006);
955 * Now scan this big bucket [ss] so as to synthesise the
956 * sorted order for small buckets [t, ss] for all t,
957 * including, magically, the bucket [ss,ss] too.
958 * This will avoid doing Real Work in subsequent Step 1's.
961 for (j = 0; j <= 255; j++) {
962 copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
963 copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
965 for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
971 ptr[copyStart[c1]++] = k;
973 for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
979 ptr[copyEnd[c1]--] = k;
983 AssertH((copyStart[ss]-1 == copyEnd[ss])
985 /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
986 * Necessity for this case is demonstrated by compressing
987 * a sequence of approximately 48.5 million of character
988 * 251; 1.0.0/1.0.1 will then die here. */
989 (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
992 for (j = 0; j <= 255; j++)
993 ftab[(j << 8) + ss] |= SETMASK;
997 * The [ss] big bucket is now done. Record this fact,
998 * and update the quadrant descriptors. Remember to
999 * update quadrants in the overshoot area too, if
1000 * necessary. The "if (i < 255)" test merely skips
1001 * this updating for the last bucket processed, since
1002 * updating for the last bucket is pointless.
1004 * The quadrant array provides a way to incrementally
1005 * cache sort orderings, as they appear, so as to
1006 * make subsequent comparisons in fullGtU() complete
1007 * faster. For repetitive blocks this makes a big
1008 * difference (but not big enough to be able to avoid
1009 * the fallback sorting mechanism, exponential radix sort).
1011 * The precise meaning is: at all times:
1013 * for 0 <= i < nblock and 0 <= j <= nblock
1015 * if block[i] != block[j],
1017 * then the relative values of quadrant[i] and
1018 * quadrant[j] are meaningless.
1021 * if quadrant[i] < quadrant[j]
1022 * then the string starting at i lexicographically
1023 * precedes the string starting at j
1025 * else if quadrant[i] > quadrant[j]
1026 * then the string starting at j lexicographically
1027 * precedes the string starting at i
1030 * the relative ordering of the strings starting
1031 * at i and j has not yet been determined.
1037 int32_t bbStart = ftab[ss << 8] & CLEARMASK;
1038 int32_t bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
1041 while ((bbSize >> shifts) > 65534) shifts++;
1043 for (j = bbSize-1; j >= 0; j--) {
1044 int32_t a2update = ptr[bbStart + j];
1045 uint16_t qVal = (uint16_t)(j >> shifts);
1046 quadrant[a2update] = qVal;
1047 if (a2update < BZ_N_OVERSHOOT)
1048 quadrant[a2update + nblock] = qVal;
1050 AssertH(((bbSize-1) >> shifts) <= 65535, 1002);
1061 /*---------------------------------------------*/
1064 * arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
1065 * ((UChar*)arr2)[0 .. nblock-1] holds block
1066 * arr1 exists for [0 .. nblock-1]
1069 * ((UChar*)arr2) [0 .. nblock-1] holds block
1070 * All other areas of block destroyed
1071 * ftab[0 .. 65536] destroyed
1072 * arr1[0 .. nblock-1] holds sorted order
1075 void BZ2_blockSort(EState* s)
1077 /* In original bzip2 1.0.4, it's a parameter, but 30
1078 * should work ok. */
1079 enum { wfact = 30 };
1081 uint32_t* ptr = s->ptr;
1082 UChar* block = s->block;
1083 uint32_t* ftab = s->ftab;
1084 int32_t nblock = s->nblock;
1089 if (nblock < 10000) {
1090 fallbackSort(s->arr1, s->arr2, ftab, nblock);
1092 /* Calculate the location for quadrant, remembering to get
1093 * the alignment right. Assumes that &(block[0]) is at least
1094 * 2-byte aligned -- this should be ok since block is really
1095 * the first section of arr2.
1097 i = nblock + BZ_N_OVERSHOOT;
1099 quadrant = (uint16_t*)(&(block[i]));
1101 /* (wfact-1) / 3 puts the default-factor-30
1102 * transition point at very roughly the same place as
1103 * with v0.1 and v0.9.0.
1104 * Not that it particularly matters any more, since the
1105 * resulting compressed stream is now the same regardless
1106 * of whether or not we use the main sort or fallback sort.
1108 budget = nblock * ((wfact-1) / 3);
1110 mainSort(ptr, block, quadrant, ftab, nblock, &budget);
1112 fallbackSort(s->arr1, s->arr2, ftab, nblock);
1117 for (i = 0; i < s->nblock; i++)
1119 s->origPtr = i; break;
1122 AssertH(s->origPtr != -1, 1003);
1126 /*-------------------------------------------------------------*/
1127 /*--- end blocksort.c ---*/
1128 /*-------------------------------------------------------------*/