File Coverage

blocksort.c
Criterion Covered Total %
statement 404 429 94.1
branch 267 328 81.4
condition n/a
subroutine n/a
pod n/a
total 671 757 88.6


line stmt bran cond sub pod time code
1              
2             /*-------------------------------------------------------------*/
3             /*--- Block sorting machinery ---*/
4             /*--- blocksort.c ---*/
5             /*-------------------------------------------------------------*/
6              
7             /* ------------------------------------------------------------------
8             This file is part of bzip2/libbzip2, a program and library for
9             lossless, block-sorting data compression.
10              
11             bzip2/libbzip2 version 1.0.8 of 13 July 2019
12             Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
13              
14             Please read the WARNING, DISCLAIMER and PATENTS sections in the
15             README file.
16              
17             This program is released under the terms of the license contained
18             in the file LICENSE.
19             ------------------------------------------------------------------ */
20              
21              
22             #include "bzlib_private.h"
23              
24             /*---------------------------------------------*/
25             /*--- Fallback O(N log(N)^2) sorting ---*/
26             /*--- algorithm, for repetitive blocks ---*/
27             /*---------------------------------------------*/
28              
29             /*---------------------------------------------*/
30             static
31             __inline__
32 6452           void fallbackSimpleSort ( UInt32* fmap,
33             UInt32* eclass,
34             Int32 lo,
35             Int32 hi )
36             {
37             Int32 i, j, tmp;
38             UInt32 ec_tmp;
39              
40 6452 100         if (lo == hi) return;
41              
42 6224 100         if (hi - lo > 3) {
43 11676 100         for ( i = hi-4; i >= lo; i-- ) {
44 8877           tmp = fmap[i];
45 8877           ec_tmp = eclass[tmp];
46 11150 100         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
    100          
47 2273           fmap[j-4] = fmap[j];
48 8877           fmap[j-4] = tmp;
49             }
50             }
51              
52 25060 100         for ( i = hi-1; i >= lo; i-- ) {
53 18836           tmp = fmap[i];
54 18836           ec_tmp = eclass[tmp];
55 27182 100         for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
    100          
56 8346           fmap[j-1] = fmap[j];
57 18836           fmap[j-1] = tmp;
58             }
59             }
60              
61              
62             /*---------------------------------------------*/
63             #define fswap(zz1, zz2) \
64             { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
65              
66             #define fvswap(zzp1, zzp2, zzn) \
67             { \
68             Int32 yyp1 = (zzp1); \
69             Int32 yyp2 = (zzp2); \
70             Int32 yyn = (zzn); \
71             while (yyn > 0) { \
72             fswap(fmap[yyp1], fmap[yyp2]); \
73             yyp1++; yyp2++; yyn--; \
74             } \
75             }
76              
77              
78             #define fmin(a,b) ((a) < (b)) ? (a) : (b)
79              
80             #define fpush(lz,hz) { stackLo[sp] = lz; \
81             stackHi[sp] = hz; \
82             sp++; }
83              
84             #define fpop(lz,hz) { sp--; \
85             lz = stackLo[sp]; \
86             hz = stackHi[sp]; }
87              
88             #define FALLBACK_QSORT_SMALL_THRESH 10
89             #define FALLBACK_QSORT_STACK_SIZE 100
90              
91              
92             static
93 1601           void fallbackQSort3 ( UInt32* fmap,
94             UInt32* eclass,
95             Int32 loSt,
96             Int32 hiSt )
97             {
98             Int32 unLo, unHi, ltLo, gtHi, n, m;
99             Int32 sp, lo, hi;
100             UInt32 med, r, r3;
101             Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
102             Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
103              
104 1601           r = 0;
105              
106 1601           sp = 0;
107 1601           fpush ( loSt, hiSt );
108              
109 13748 100         while (sp > 0) {
110              
111 12147 50         AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
112              
113 12147           fpop ( lo, hi );
114 12147 100         if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
115 6452           fallbackSimpleSort ( fmap, eclass, lo, hi );
116 6452           continue;
117             }
118              
119             /* Random partitioning. Median of 3 sometimes fails to
120             avoid bad cases. Median of 9 seems to help but
121             looks rather expensive. This too seems to work but
122             is cheaper. Guidance for the magic constants
123             7621 and 32768 is taken from Sedgewick's algorithms
124             book, chapter 35.
125             */
126 5695           r = ((r * 7621) + 1) % 32768;
127 5695           r3 = r % 3;
128 5695 100         if (r3 == 0) med = eclass[fmap[lo]]; else
129 4659 100         if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
130 1974           med = eclass[fmap[hi]];
131              
132 5695           unLo = ltLo = lo;
133 5695           unHi = gtHi = hi;
134              
135 19120           while (1) {
136             while (1) {
137 1083660 100         if (unLo > unHi) break;
138 1081190           n = (Int32)eclass[fmap[unLo]] - (Int32)med;
139 1081190 100         if (n == 0) {
140 972004           fswap(fmap[unLo], fmap[ltLo]);
141 972004           ltLo++; unLo++;
142 972004           continue;
143             };
144 109186 100         if (n > 0) break;
145 86841           unLo++;
146             }
147             while (1) {
148 102682 100         if (unLo > unHi) break;
149 96987           n = (Int32)eclass[fmap[unHi]] - (Int32)med;
150 96987 100         if (n == 0) {
151 6793           fswap(fmap[unHi], fmap[gtHi]);
152 6793           gtHi--; unHi--;
153 6793           continue;
154             };
155 90194 100         if (n < 0) break;
156 71074           unHi--;
157             }
158 24815 100         if (unLo > unHi) break;
159 19120           fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
160             }
161              
162             AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
163              
164 5695 100         if (gtHi < ltLo) continue;
165              
166 27570 100         n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
167 10067 100         m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
168              
169 5273           n = lo + unLo - ltLo - 1;
170 5273           m = hi - (gtHi - unHi) + 1;
171              
172 5273 100         if (n - lo > hi - m) {
173 1976           fpush ( lo, n );
174 1976           fpush ( m, hi );
175             } else {
176 3297           fpush ( m, hi );
177 3297           fpush ( lo, n );
178             }
179             }
180 1601           }
181              
182             #undef fmin
183             #undef fpush
184             #undef fpop
185             #undef fswap
186             #undef fvswap
187             #undef FALLBACK_QSORT_SMALL_THRESH
188             #undef FALLBACK_QSORT_STACK_SIZE
189              
190              
191             /*---------------------------------------------*/
192             /* Pre:
193             nblock > 0
194             eclass exists for [0 .. nblock-1]
195             ((UChar*)eclass) [0 .. nblock-1] holds block
196             ptr exists for [0 .. nblock-1]
197              
198             Post:
199             ((UChar*)eclass) [0 .. nblock-1] holds block
200             All other areas of eclass destroyed
201             fmap [0 .. nblock-1] holds sorted order
202             bhtab [ 0 .. 2+(nblock/32) ] destroyed
203             */
204              
205             #define SET_BH(zz) bhtab[(zz) >> 5] |= ((UInt32)1 << ((zz) & 31))
206             #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~((UInt32)1 << ((zz) & 31))
207             #define ISSET_BH(zz) (bhtab[(zz) >> 5] & ((UInt32)1 << ((zz) & 31)))
208             #define WORD_BH(zz) bhtab[(zz) >> 5]
209             #define UNALIGNED_BH(zz) ((zz) & 0x01f)
210              
211             static
212 20           void fallbackSort ( UInt32* fmap,
213             UInt32* eclass,
214             UInt32* bhtab,
215             Int32 nblock,
216             Int32 verb )
217             {
218             Int32 ftab[257];
219             Int32 ftabCopy[256];
220             Int32 H, i, j, k, l, r, cc, cc1;
221             Int32 nNotDone;
222             Int32 nBhtab;
223 20           UChar* eclass8 = (UChar*)eclass;
224              
225             /*--
226             Initial 1-char radix sort to generate
227             initial fmap and initial BH bits.
228             --*/
229             if (verb >= 4)
230             VPrintf0 ( " bucket sorting ...\n" );
231 5160 100         for (i = 0; i < 257; i++) ftab[i] = 0;
232 75415 100         for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
233 5140 100         for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
234 5140 100         for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
235              
236 75415 100         for (i = 0; i < nblock; i++) {
237 75395           j = eclass8[i];
238 75395           k = ftab[j] - 1;
239 75395           ftab[j] = k;
240 75395           fmap[k] = i;
241             }
242              
243 20           nBhtab = 2 + (nblock / 32);
244 2403 100         for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
245 5140 100         for (i = 0; i < 256; i++) SET_BH(ftab[i]);
246              
247             /*--
248             Inductively refine the buckets. Kind-of an
249             "exponential radix sort" (!), inspired by the
250             Manber-Myers suffix array construction algorithm.
251             --*/
252              
253             /*-- set sentinel bits for block-end detection --*/
254 660 100         for (i = 0; i < 32; i++) {
255 640           SET_BH(nblock + 2*i);
256 640           CLEAR_BH(nblock + 2*i + 1);
257             }
258              
259             /*-- the log(N) loop --*/
260 20           H = 1;
261             while (1) {
262              
263 62           if (verb >= 4)
264             VPrintf1 ( " depth %6d has ", H );
265              
266 82           j = 0;
267 1054715 100         for (i = 0; i < nblock; i++) {
268 1054633 100         if (ISSET_BH(i)) j = i;
269 1054633 100         k = fmap[i] - H; if (k < 0) k += nblock;
270 1054633           eclass[k] = j;
271             }
272              
273 82           nNotDone = 0;
274 82           r = -1;
275             while (1) {
276              
277             /*-- find the next non-singleton bucket --*/
278 1683           k = r + 1;
279 9140 100         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
    100          
280 1683 100         if (ISSET_BH(k)) {
281 1762 100         while (WORD_BH(k) == 0xffffffff) k += 32;
282 5200 100         while (ISSET_BH(k)) k++;
283             }
284 1683           l = k - 1;
285 1683 100         if (l >= nblock) break;
286 19082 100         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
    100          
287 1601 100         if (!ISSET_BH(k)) {
288 31243 100         while (WORD_BH(k) == 0x00000000) k += 32;
289 13495 100         while (!ISSET_BH(k)) k++;
290             }
291 1601           r = k - 1;
292 1601 50         if (r >= nblock) break;
293              
294             /*-- now [l, r] bracket current bucket --*/
295 1601 50         if (r > l) {
296 1601           nNotDone += (r - l + 1);
297 1601           fallbackQSort3 ( fmap, eclass, l, r );
298              
299             /*-- scan bucket and generate header bits-- */
300 1601           cc = -1;
301 1003231 100         for (i = l; i <= r; i++) {
302 1001630           cc1 = eclass[fmap[i]];
303 1001630 100         if (cc != cc1) { SET_BH(i); cc = cc1; };
304             }
305             }
306             }
307              
308             if (verb >= 4)
309             VPrintf1 ( "%6d unresolved strings\n", nNotDone );
310              
311 82           H *= 2;
312 82 100         if (H > nblock || nNotDone == 0) break;
    100          
313             }
314              
315             /*--
316             Reconstruct the original block in
317             eclass8 [0 .. nblock-1], since the
318             previous phase destroyed it.
319             --*/
320             if (verb >= 4)
321             VPrintf0 ( " reconstructing block ...\n" );
322 20           j = 0;
323 75415 100         for (i = 0; i < nblock; i++) {
324 77945 100         while (ftabCopy[j] == 0) j++;
325 75395           ftabCopy[j]--;
326 75395           eclass8[fmap[i]] = (UChar)j;
327             }
328 20 50         AssertH ( j < 256, 1005 );
329 20           }
330              
331             #undef SET_BH
332             #undef CLEAR_BH
333             #undef ISSET_BH
334             #undef WORD_BH
335             #undef UNALIGNED_BH
336              
337              
338             /*---------------------------------------------*/
339             /*--- The main, O(N^2 log(N)) sorting ---*/
340             /*--- algorithm. Faster for "normal" ---*/
341             /*--- non-repetitive blocks. ---*/
342             /*---------------------------------------------*/
343              
344             /*---------------------------------------------*/
345             static
346             __inline__
347 9119           Bool mainGtU ( UInt32 i1,
348             UInt32 i2,
349             UChar* block,
350             UInt16* quadrant,
351             UInt32 nblock,
352             Int32* budget )
353             {
354             Int32 k;
355             UChar c1, c2;
356             UInt16 s1, s2;
357              
358             AssertD ( i1 != i2, "mainGtU" );
359             /* 1 */
360 9119           c1 = block[i1]; c2 = block[i2];
361 9119 100         if (c1 != c2) return (c1 > c2);
362 245           i1++; i2++;
363             /* 2 */
364 245           c1 = block[i1]; c2 = block[i2];
365 245 100         if (c1 != c2) return (c1 > c2);
366 201           i1++; i2++;
367             /* 3 */
368 201           c1 = block[i1]; c2 = block[i2];
369 201 50         if (c1 != c2) return (c1 > c2);
370 201           i1++; i2++;
371             /* 4 */
372 201           c1 = block[i1]; c2 = block[i2];
373 201 50         if (c1 != c2) return (c1 > c2);
374 201           i1++; i2++;
375             /* 5 */
376 201           c1 = block[i1]; c2 = block[i2];
377 201 50         if (c1 != c2) return (c1 > c2);
378 201           i1++; i2++;
379             /* 6 */
380 201           c1 = block[i1]; c2 = block[i2];
381 201 50         if (c1 != c2) return (c1 > c2);
382 201           i1++; i2++;
383             /* 7 */
384 201           c1 = block[i1]; c2 = block[i2];
385 201 50         if (c1 != c2) return (c1 > c2);
386 201           i1++; i2++;
387             /* 8 */
388 201           c1 = block[i1]; c2 = block[i2];
389 201 50         if (c1 != c2) return (c1 > c2);
390 201           i1++; i2++;
391             /* 9 */
392 201           c1 = block[i1]; c2 = block[i2];
393 201 50         if (c1 != c2) return (c1 > c2);
394 201           i1++; i2++;
395             /* 10 */
396 201           c1 = block[i1]; c2 = block[i2];
397 201 50         if (c1 != c2) return (c1 > c2);
398 201           i1++; i2++;
399             /* 11 */
400 201           c1 = block[i1]; c2 = block[i2];
401 201 50         if (c1 != c2) return (c1 > c2);
402 201           i1++; i2++;
403             /* 12 */
404 201           c1 = block[i1]; c2 = block[i2];
405 201 50         if (c1 != c2) return (c1 > c2);
406 201           i1++; i2++;
407              
408 201           k = nblock + 8;
409              
410             do {
411             /* 1 */
412 588797           c1 = block[i1]; c2 = block[i2];
413 588797 100         if (c1 != c2) return (c1 > c2);
414 588781           s1 = quadrant[i1]; s2 = quadrant[i2];
415 588781 50         if (s1 != s2) return (s1 > s2);
416 588781           i1++; i2++;
417             /* 2 */
418 588781           c1 = block[i1]; c2 = block[i2];
419 588781 100         if (c1 != c2) return (c1 > c2);
420 588764           s1 = quadrant[i1]; s2 = quadrant[i2];
421 588764 50         if (s1 != s2) return (s1 > s2);
422 588764           i1++; i2++;
423             /* 3 */
424 588764           c1 = block[i1]; c2 = block[i2];
425 588764 100         if (c1 != c2) return (c1 > c2);
426 588748           s1 = quadrant[i1]; s2 = quadrant[i2];
427 588748 50         if (s1 != s2) return (s1 > s2);
428 588748           i1++; i2++;
429             /* 4 */
430 588748           c1 = block[i1]; c2 = block[i2];
431 588748 100         if (c1 != c2) return (c1 > c2);
432 588732           s1 = quadrant[i1]; s2 = quadrant[i2];
433 588732 50         if (s1 != s2) return (s1 > s2);
434 588732           i1++; i2++;
435             /* 5 */
436 588732           c1 = block[i1]; c2 = block[i2];
437 588732 100         if (c1 != c2) return (c1 > c2);
438 588716           s1 = quadrant[i1]; s2 = quadrant[i2];
439 588716 50         if (s1 != s2) return (s1 > s2);
440 588716           i1++; i2++;
441             /* 6 */
442 588716           c1 = block[i1]; c2 = block[i2];
443 588716 100         if (c1 != c2) return (c1 > c2);
444 588700           s1 = quadrant[i1]; s2 = quadrant[i2];
445 588700 50         if (s1 != s2) return (s1 > s2);
446 588700           i1++; i2++;
447             /* 7 */
448 588700           c1 = block[i1]; c2 = block[i2];
449 588700 100         if (c1 != c2) return (c1 > c2);
450 588684           s1 = quadrant[i1]; s2 = quadrant[i2];
451 588684 50         if (s1 != s2) return (s1 > s2);
452 588684           i1++; i2++;
453             /* 8 */
454 588684           c1 = block[i1]; c2 = block[i2];
455 588684 100         if (c1 != c2) return (c1 > c2);
456 588668           s1 = quadrant[i1]; s2 = quadrant[i2];
457 588668 50         if (s1 != s2) return (s1 > s2);
458 588668           i1++; i2++;
459              
460 588668 100         if (i1 >= nblock) i1 -= nblock;
461 588668 100         if (i2 >= nblock) i2 -= nblock;
462              
463 588668           k -= 8;
464 588668           (*budget)--;
465             }
466 588668 100         while (k >= 0);
467              
468 72           return False;
469             }
470              
471              
472             /*---------------------------------------------*/
473             /*--
474             Knuth's increments seem to work better
475             than Incerpi-Sedgewick here. Possibly
476             because the number of elems to sort is
477             usually small, typically <= 20.
478             --*/
479             static
480             Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
481             9841, 29524, 88573, 265720,
482             797161, 2391484 };
483              
484             static
485 5793           void mainSimpleSort ( UInt32* ptr,
486             UChar* block,
487             UInt16* quadrant,
488             Int32 nblock,
489             Int32 lo,
490             Int32 hi,
491             Int32 d,
492             Int32* budget )
493             {
494             Int32 i, j, h, bigN, hp;
495             UInt32 v;
496              
497 5793           bigN = hi - lo + 1;
498 5793 50         if (bigN < 2) return;
499              
500 5793           hp = 0;
501 11644 100         while (incs[hp] < bigN) hp++;
502 5793           hp--;
503              
504 11631 100         for (; hp >= 0; hp--) {
505 5840           h = incs[hp];
506              
507 5840           i = lo + h;
508             while (True) {
509              
510             /*-- copy 1 --*/
511 6189 100         if (i > hi) break;
512 5952           v = ptr[i];
513 5952           j = i;
514 11947 100         while ( mainGtU (
515 5995           ptr[j-h]+d, v+d, block, quadrant, nblock, budget
516             ) ) {
517 3031           ptr[j] = ptr[j-h];
518 3031           j = j - h;
519 3031 100         if (j <= (lo + h - 1)) break;
520             }
521 5952           ptr[j] = v;
522 5952           i++;
523              
524             /*-- copy 2 --*/
525 5952 100         if (i > hi) break;
526 1476           v = ptr[i];
527 1476           j = i;
528 3904 100         while ( mainGtU (
529 2428           ptr[j-h]+d, v+d, block, quadrant, nblock, budget
530             ) ) {
531 1469           ptr[j] = ptr[j-h];
532 1469           j = j - h;
533 1469 100         if (j <= (lo + h - 1)) break;
534             }
535 1476           ptr[j] = v;
536 1476           i++;
537              
538             /*-- copy 3 --*/
539 1476 100         if (i > hi) break;
540 351           v = ptr[i];
541 351           j = i;
542 1047 100         while ( mainGtU (
543 696           ptr[j-h]+d, v+d, block, quadrant, nblock, budget
544             ) ) {
545 454           ptr[j] = ptr[j-h];
546 454           j = j - h;
547 454 100         if (j <= (lo + h - 1)) break;
548             }
549 351           ptr[j] = v;
550 351           i++;
551              
552 351 100         if (*budget < 0) return;
553             }
554             }
555             }
556              
557              
558             /*---------------------------------------------*/
559             /*--
560             The following is an implementation of
561             an elegant 3-way quicksort for strings,
562             described in a paper "Fast Algorithms for
563             Sorting and Searching Strings", by Robert
564             Sedgewick and Jon L. Bentley.
565             --*/
566              
567             #define mswap(zz1, zz2) \
568             { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
569              
570             #define mvswap(zzp1, zzp2, zzn) \
571             { \
572             Int32 yyp1 = (zzp1); \
573             Int32 yyp2 = (zzp2); \
574             Int32 yyn = (zzn); \
575             while (yyn > 0) { \
576             mswap(ptr[yyp1], ptr[yyp2]); \
577             yyp1++; yyp2++; yyn--; \
578             } \
579             }
580              
581             static
582             __inline__
583 26           UChar mmed3 ( UChar a, UChar b, UChar c )
584             {
585             UChar t;
586 26 50         if (a > b) { t = a; a = b; b = t; };
587 26 50         if (b > c) {
588 0           b = c;
589 0 0         if (a > b) b = a;
590             }
591 26           return b;
592             }
593              
594             #define mmin(a,b) ((a) < (b)) ? (a) : (b)
595              
596             #define mpush(lz,hz,dz) { stackLo[sp] = lz; \
597             stackHi[sp] = hz; \
598             stackD [sp] = dz; \
599             sp++; }
600              
601             #define mpop(lz,hz,dz) { sp--; \
602             lz = stackLo[sp]; \
603             hz = stackHi[sp]; \
604             dz = stackD [sp]; }
605              
606              
607             #define mnextsize(az) (nextHi[az]-nextLo[az])
608              
609             #define mnextswap(az,bz) \
610             { Int32 tz; \
611             tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
612             tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
613             tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
614              
615              
616             #define MAIN_QSORT_SMALL_THRESH 20
617             #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
618             #define MAIN_QSORT_STACK_SIZE 100
619              
620             static
621 5793           void mainQSort3 ( UInt32* ptr,
622             UChar* block,
623             UInt16* quadrant,
624             Int32 nblock,
625             Int32 loSt,
626             Int32 hiSt,
627             Int32 dSt,
628             Int32* budget )
629             {
630             Int32 unLo, unHi, ltLo, gtHi, n, m, med;
631             Int32 sp, lo, hi, d;
632              
633             Int32 stackLo[MAIN_QSORT_STACK_SIZE];
634             Int32 stackHi[MAIN_QSORT_STACK_SIZE];
635             Int32 stackD [MAIN_QSORT_STACK_SIZE];
636              
637             Int32 nextLo[3];
638             Int32 nextHi[3];
639             Int32 nextD [3];
640              
641 5793           sp = 0;
642 5793           mpush ( loSt, hiSt, dSt );
643              
644 11610 100         while (sp > 0) {
645              
646 5819 50         AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
647              
648 5819           mpop ( lo, hi, d );
649 5819 100         if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
    100          
650             d > MAIN_QSORT_DEPTH_THRESH) {
651 5793           mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
652 5793 100         if (*budget < 0) return;
653 5791           continue;
654             }
655              
656 26           med = (Int32)
657 26           mmed3 ( block[ptr[ lo ]+d],
658 26           block[ptr[ hi ]+d],
659 26           block[ptr[ (lo+hi)>>1 ]+d] );
660              
661 26           unLo = ltLo = lo;
662 26           unHi = gtHi = hi;
663              
664 0           while (True) {
665             while (True) {
666 39039 100         if (unLo > unHi) break;
667 39013           n = ((Int32)block[ptr[unLo]+d]) - med;
668 39013 50         if (n == 0) {
669 39013           mswap(ptr[unLo], ptr[ltLo]);
670 39013           ltLo++; unLo++; continue;
671             };
672 0 0         if (n > 0) break;
673 0           unLo++;
674             }
675             while (True) {
676 26 50         if (unLo > unHi) break;
677 0           n = ((Int32)block[ptr[unHi]+d]) - med;
678 0 0         if (n == 0) {
679 0           mswap(ptr[unHi], ptr[gtHi]);
680 0           gtHi--; unHi--; continue;
681             };
682 0 0         if (n < 0) break;
683 0           unHi--;
684             }
685 26 50         if (unLo > unHi) break;
686 0           mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
687             }
688              
689             AssertD ( unHi == unLo-1, "mainQSort3(2)" );
690              
691 26 50         if (gtHi < ltLo) {
692 26           mpush(lo, hi, d+1 );
693 26           continue;
694             }
695              
696 0 0         n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
697 0 0         m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
698              
699 0           n = lo + unLo - ltLo - 1;
700 0           m = hi - (gtHi - unHi) + 1;
701              
702 0           nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
703 0           nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
704 0           nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
705              
706 0 0         if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
707 0 0         if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
708 0 0         if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
709              
710             AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
711             AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
712              
713 0           mpush (nextLo[0], nextHi[0], nextD[0]);
714 0           mpush (nextLo[1], nextHi[1], nextD[1]);
715 0           mpush (nextLo[2], nextHi[2], nextD[2]);
716             }
717             }
718              
719             #undef mswap
720             #undef mvswap
721             #undef mpush
722             #undef mpop
723             #undef mmin
724             #undef mnextsize
725             #undef mnextswap
726             #undef MAIN_QSORT_SMALL_THRESH
727             #undef MAIN_QSORT_DEPTH_THRESH
728             #undef MAIN_QSORT_STACK_SIZE
729              
730              
731             /*---------------------------------------------*/
732             /* Pre:
733             nblock > N_OVERSHOOT
734             block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
735             ((UChar*)block32) [0 .. nblock-1] holds block
736             ptr exists for [0 .. nblock-1]
737              
738             Post:
739             ((UChar*)block32) [0 .. nblock-1] holds block
740             All other areas of block32 destroyed
741             ftab [0 .. 65536 ] destroyed
742             ptr [0 .. nblock-1] holds sorted order
743             if (*budget < 0), sorting was abandoned
744             */
745              
746             #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
747             #define SETMASK (1 << 21)
748             #define CLEARMASK (~(SETMASK))
749              
750             static
751 3           void mainSort ( UInt32* ptr,
752             UChar* block,
753             UInt16* quadrant,
754             UInt32* ftab,
755             Int32 nblock,
756             Int32 verb,
757             Int32* budget )
758             {
759             Int32 i, j, k, ss, sb;
760             Int32 runningOrder[256];
761             Bool bigDone[256];
762             Int32 copyStart[256];
763             Int32 copyEnd [256];
764             UChar c1;
765             Int32 numQSorted;
766             UInt16 s;
767              
768             ((void)numQSorted); /* Silence variable ‘numQSorted’ set but not used warning */
769              
770             if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
771              
772             /*-- set up the 2-byte frequency table --*/
773 196614 100         for (i = 65536; i >= 0; i--) ftab[i] = 0;
774              
775 3           j = block[0] << 8;
776 3           i = nblock-1;
777 28762 100         for (; i >= 3; i -= 4) {
778 28759           quadrant[i] = 0;
779 28759           j = (j >> 8) | ( ((UInt16)block[i]) << 8);
780 28759           ftab[j]++;
781 28759           quadrant[i-1] = 0;
782 28759           j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
783 28759           ftab[j]++;
784 28759           quadrant[i-2] = 0;
785 28759           j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
786 28759           ftab[j]++;
787 28759           quadrant[i-3] = 0;
788 28759           j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
789 28759           ftab[j]++;
790             }
791 4 100         for (; i >= 0; i--) {
792 1           quadrant[i] = 0;
793 1           j = (j >> 8) | ( ((UInt16)block[i]) << 8);
794 1           ftab[j]++;
795             }
796              
797             /*-- (emphasises close relationship of block & quadrant) --*/
798 105 100         for (i = 0; i < BZ_N_OVERSHOOT; i++) {
799 102           block [nblock+i] = block[i];
800 102           quadrant[nblock+i] = 0;
801             }
802              
803             if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
804              
805             /*-- Complete the initial radix sort --*/
806 196611 100         for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
807              
808 3           s = block[0] << 8;
809 3           i = nblock-1;
810 28762 100         for (; i >= 3; i -= 4) {
811 28759           s = (s >> 8) | (block[i] << 8);
812 28759           j = ftab[s] -1;
813 28759           ftab[s] = j;
814 28759           ptr[j] = i;
815 28759           s = (s >> 8) | (block[i-1] << 8);
816 28759           j = ftab[s] -1;
817 28759           ftab[s] = j;
818 28759           ptr[j] = i-1;
819 28759           s = (s >> 8) | (block[i-2] << 8);
820 28759           j = ftab[s] -1;
821 28759           ftab[s] = j;
822 28759           ptr[j] = i-2;
823 28759           s = (s >> 8) | (block[i-3] << 8);
824 28759           j = ftab[s] -1;
825 28759           ftab[s] = j;
826 28759           ptr[j] = i-3;
827             }
828 4 100         for (; i >= 0; i--) {
829 1           s = (s >> 8) | (block[i] << 8);
830 1           j = ftab[s] -1;
831 1           ftab[s] = j;
832 1           ptr[j] = i;
833             }
834              
835             /*--
836             Now ftab contains the first loc of every small bucket.
837             Calculate the running order, from smallest to largest
838             big bucket.
839             --*/
840 771 100         for (i = 0; i <= 255; i++) {
841 768           bigDone [i] = False;
842 768           runningOrder[i] = i;
843             }
844              
845             {
846             Int32 vv;
847 3           Int32 h = 1;
848 15 100         do h = 3 * h + 1; while (h <= 256);
849             do {
850 15           h = h / 3;
851 3318 100         for (i = h; i <= 255; i++) {
852 3303           vv = runningOrder[i];
853 3303           j = i;
854 4596 100         while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
855 1452           runningOrder[j] = runningOrder[j-h];
856 1452           j = j - h;
857 1452 100         if (j <= (h - 1)) goto zero;
858             }
859 3144           zero:
860 3303           runningOrder[j] = vv;
861             }
862 15 100         } while (h != 1);
863             }
864              
865             /*--
866             The main sorting loop.
867             --*/
868              
869 3           numQSorted = 0;
870              
871 738 100         for (i = 0; i <= 255; i++) {
872              
873             /*--
874             Process big buckets, starting with the least full.
875             Basically this is a 3-step process in which we call
876             mainQSort3 to sort the small buckets [ss, j], but
877             also make a big effort to avoid the calls if we can.
878             --*/
879 737           ss = runningOrder[i];
880              
881             /*--
882             Step 1:
883             Complete the big bucket [ss] by quicksorting
884             any unsorted small buckets [ss, j], for j != ss.
885             Hopefully previous pointer-scanning phases have already
886             completed many of the small buckets [ss, j], so
887             we don't have to sort them at all.
888             --*/
889 189112 100         for (j = 0; j <= 255; j++) {
890 188377 100         if (j != ss) {
891 187640           sb = (ss << 8) + j;
892 187640 100         if ( ! (ftab[sb] & SETMASK) ) {
893 97680           Int32 lo = ftab[sb] & CLEARMASK;
894 97680           Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
895 97680 100         if (hi > lo) {
896             if (verb >= 4)
897             VPrintf4 ( " qsort [0x%x, 0x%x] "
898             "done %d this %d\n",
899             ss, j, numQSorted, hi - lo + 1 );
900 5793           mainQSort3 (
901             ptr, block, quadrant, nblock,
902             lo, hi, BZ_N_RADIX, budget
903             );
904 5793           numQSorted += (hi - lo + 1);
905 5793 100         if (*budget < 0) return;
906             }
907             }
908 187638           ftab[sb] |= SETMASK;
909             }
910             }
911              
912 735 50         AssertH ( !bigDone[ss], 1006 );
913              
914             /*--
915             Step 2:
916             Now scan this big bucket [ss] so as to synthesise the
917             sorted order for small buckets [t, ss] for all t,
918             including, magically, the bucket [ss,ss] too.
919             This will avoid doing Real Work in subsequent Step 1's.
920             --*/
921             {
922 188895 100         for (j = 0; j <= 255; j++) {
923 188160           copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
924 188160           copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
925             }
926 25741 100         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
927 25006 50         k = ptr[j]-1; if (k < 0) k += nblock;
928 25006           c1 = block[k];
929 25006 100         if (!bigDone[c1])
930 12666           ptr[ copyStart[c1]++ ] = k;
931             }
932 25733 100         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
933 24998 100         k = ptr[j]-1; if (k < 0) k += nblock;
934 24998           c1 = block[k];
935 24998 100         if (!bigDone[c1])
936 12365           ptr[ copyEnd[c1]-- ] = k;
937             }
938             }
939              
940 735 50         AssertH ( (copyStart[ss]-1 == copyEnd[ss])
    0          
    0          
941             ||
942             /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
943             Necessity for this case is demonstrated by compressing
944             a sequence of approximately 48.5 million of character
945             251; 1.0.0/1.0.1 will then die here. */
946             (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
947             1007 )
948              
949 188895 100         for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
950              
951             /*--
952             Step 3:
953             The [ss] big bucket is now done. Record this fact,
954             and update the quadrant descriptors. Remember to
955             update quadrants in the overshoot area too, if
956             necessary. The "if (i < 255)" test merely skips
957             this updating for the last bucket processed, since
958             updating for the last bucket is pointless.
959              
960             The quadrant array provides a way to incrementally
961             cache sort orderings, as they appear, so as to
962             make subsequent comparisons in fullGtU() complete
963             faster. For repetitive blocks this makes a big
964             difference (but not big enough to be able to avoid
965             the fallback sorting mechanism, exponential radix sort).
966              
967             The precise meaning is: at all times:
968              
969             for 0 <= i < nblock and 0 <= j <= nblock
970              
971             if block[i] != block[j],
972              
973             then the relative values of quadrant[i] and
974             quadrant[j] are meaningless.
975              
976             else {
977             if quadrant[i] < quadrant[j]
978             then the string starting at i lexicographically
979             precedes the string starting at j
980              
981             else if quadrant[i] > quadrant[j]
982             then the string starting at j lexicographically
983             precedes the string starting at i
984              
985             else
986             the relative ordering of the strings starting
987             at i and j has not yet been determined.
988             }
989             --*/
990 735           bigDone[ss] = True;
991              
992 735 100         if (i < 255) {
993 734           Int32 bbStart = ftab[ss << 8] & CLEARMASK;
994 734           Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
995 734           Int32 shifts = 0;
996              
997 734 50         while ((bbSize >> shifts) > 65534) shifts++;
998              
999 50502 100         for (j = bbSize-1; j >= 0; j--) {
1000 49768           Int32 a2update = ptr[bbStart + j];
1001 49768           UInt16 qVal = (UInt16)(j >> shifts);
1002 49768           quadrant[a2update] = qVal;
1003 49768 100         if (a2update < BZ_N_OVERSHOOT)
1004 34           quadrant[a2update + nblock] = qVal;
1005             }
1006 734 50         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
1007             }
1008              
1009             }
1010              
1011             if (verb >= 4)
1012             VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
1013             nblock, numQSorted, nblock - numQSorted );
1014             }
1015              
1016             #undef BIGFREQ
1017             #undef SETMASK
1018             #undef CLEARMASK
1019              
1020              
1021             /*---------------------------------------------*/
1022             /* Pre:
1023             nblock > 0
1024             arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
1025             ((UChar*)arr2) [0 .. nblock-1] holds block
1026             arr1 exists for [0 .. nblock-1]
1027              
1028             Post:
1029             ((UChar*)arr2) [0 .. nblock-1] holds block
1030             All other areas of block destroyed
1031             ftab [ 0 .. 65536 ] destroyed
1032             arr1 [0 .. nblock-1] holds sorted order
1033             */
1034 21           void BZ2_blockSort ( EState* s )
1035             {
1036 21           UInt32* ptr = s->ptr;
1037 21           UChar* block = s->block;
1038 21           UInt32* ftab = s->ftab;
1039 21           Int32 nblock = s->nblock;
1040 21           Int32 verb = s->verbosity;
1041 21           Int32 wfact = s->workFactor;
1042             UInt16* quadrant;
1043             Int32 budget;
1044             Int32 budgetInit;
1045             Int32 i;
1046              
1047 21 100         if (nblock < 10000) {
1048 18           fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1049             } else {
1050             /* Calculate the location for quadrant, remembering to get
1051             the alignment right. Assumes that &(block[0]) is at least
1052             2-byte aligned -- this should be ok since block is really
1053             the first section of arr2.
1054             */
1055 3           i = nblock+BZ_N_OVERSHOOT;
1056 3 100         if (i & 1) i++;
1057 3           quadrant = (UInt16*)(&(block[i]));
1058              
1059             /* (wfact-1) / 3 puts the default-factor-30
1060             transition point at very roughly the same place as
1061             with v0.1 and v0.9.0.
1062             Not that it particularly matters any more, since the
1063             resulting compressed stream is now the same regardless
1064             of whether or not we use the main sort or fallback sort.
1065             */
1066 3 50         if (wfact < 1 ) wfact = 1;
1067 3 50         if (wfact > 100) wfact = 100;
1068 3           budgetInit = nblock * ((wfact-1) / 3);
1069 3           budget = budgetInit;
1070              
1071 3           mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
1072             if (verb >= 3)
1073             VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
1074             budgetInit - budget,
1075             nblock,
1076             (float)(budgetInit - budget) /
1077             (float)(nblock==0 ? 1 : nblock) );
1078 3 100         if (budget < 0) {
1079             if (verb >= 2)
1080             VPrintf0 ( " too repetitive; using fallback"
1081             " sorting algorithm\n" );
1082 2           fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1083             }
1084             }
1085              
1086 21           s->origPtr = -1;
1087 55588 50         for (i = 0; i < s->nblock; i++)
1088 55588 100         if (ptr[i] == 0)
1089 21           { s->origPtr = i; break; };
1090              
1091 21 50         AssertH( s->origPtr != -1, 1003 );
1092 21           }
1093              
1094              
1095             /*-------------------------------------------------------------*/
1096             /*--- end blocksort.c ---*/
1097             /*-------------------------------------------------------------*/