abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
blocksort.c File Reference
#include "bzlib_private.h"

Go to the source code of this file.

Macros

#define fswap(zz1, zz2)   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
 
#define fvswap(zzp1, zzp2, zzn)
 
#define fmin(a, b)   ((a) < (b)) ? (a) : (b)
 
#define fpush(lz, hz)
 
#define fpop(lz, hz)
 
#define FALLBACK_QSORT_SMALL_THRESH   10
 
#define FALLBACK_QSORT_STACK_SIZE   100
 
#define SET_BH(zz)   bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
 
#define CLEAR_BH(zz)   bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
 
#define ISSET_BH(zz)   (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
 
#define WORD_BH(zz)   bhtab[(zz) >> 5]
 
#define UNALIGNED_BH(zz)   ((zz) & 0x01f)
 
#define mswap(zz1, zz2)   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
 
#define mvswap(zzp1, zzp2, zzn)
 
#define mmin(a, b)   ((a) < (b)) ? (a) : (b)
 
#define mpush(lz, hz, dz)
 
#define mpop(lz, hz, dz)
 
#define mnextsize(az)   (nextHi[az]-nextLo[az])
 
#define mnextswap(az, bz)
 
#define MAIN_QSORT_SMALL_THRESH   20
 
#define MAIN_QSORT_DEPTH_THRESH   (BZ_N_RADIX + BZ_N_QSORT)
 
#define MAIN_QSORT_STACK_SIZE   100
 
#define BIGFREQ(b)   (ftab[((b)+1) << 8] - ftab[(b) << 8])
 
#define SETMASK   (1 << 21)
 
#define CLEARMASK   (~(SETMASK))
 

Functions

static
ABC_NAMESPACE_IMPL_START
__inline__ void 
fallbackSimpleSort (UInt32 *fmap, UInt32 *eclass, Int32 lo, Int32 hi)
 
static void fallbackQSort3 (UInt32 *fmap, UInt32 *eclass, Int32 loSt, Int32 hiSt)
 
static void fallbackSort (UInt32 *fmap, UInt32 *eclass, UInt32 *bhtab, Int32 nblock, Int32 verb)
 
static __inline__ Bool mainGtU (UInt32 i1, UInt32 i2, UChar *block, UInt16 *quadrant, UInt32 nblock, Int32 *budget)
 
static void mainSimpleSort (UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 lo, Int32 hi, Int32 d, Int32 *budget)
 
static __inline__ UChar mmed3 (UChar a, UChar b, UChar c)
 
static void mainQSort3 (UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 loSt, Int32 hiSt, Int32 dSt, Int32 *budget)
 
static void mainSort (UInt32 *ptr, UChar *block, UInt16 *quadrant, UInt32 *ftab, Int32 nblock, Int32 verb, Int32 *budget)
 
void BZ2_blockSort (EState *s)
 

Variables

static Int32 incs [14]
 

Macro Definition Documentation

#define BIGFREQ (   b)    (ftab[((b)+1) << 8] - ftab[(b) << 8])

Definition at line 748 of file blocksort.c.

#define CLEAR_BH (   zz)    bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))

Definition at line 208 of file blocksort.c.

#define CLEARMASK   (~(SETMASK))

Definition at line 750 of file blocksort.c.

#define FALLBACK_QSORT_SMALL_THRESH   10

Definition at line 90 of file blocksort.c.

#define FALLBACK_QSORT_STACK_SIZE   100

Definition at line 91 of file blocksort.c.

#define fmin (   a,
 
)    ((a) < (b)) ? (a) : (b)

Definition at line 80 of file blocksort.c.

#define fpop (   lz,
  hz 
)
Value:
{ sp--; \
lz = stackLo[sp]; \
hz = stackHi[sp]; }

Definition at line 86 of file blocksort.c.

#define fpush (   lz,
  hz 
)
Value:
{ stackLo[sp] = lz; \
stackHi[sp] = hz; \
sp++; }

Definition at line 82 of file blocksort.c.

#define fswap (   zz1,
  zz2 
)    { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }

Definition at line 65 of file blocksort.c.

#define fvswap (   zzp1,
  zzp2,
  zzn 
)
Value:
{ \
Int32 yyp1 = (zzp1); \
Int32 yyp2 = (zzp2); \
Int32 yyn = (zzn); \
while (yyn > 0) { \
fswap(fmap[yyp1], fmap[yyp2]); \
yyp1++; yyp2++; yyn--; \
} \
}
#define fswap(zz1, zz2)
Definition: blocksort.c:65
int Int32
Definition: bzlib_private.h:46

Definition at line 68 of file blocksort.c.

#define ISSET_BH (   zz)    (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))

Definition at line 209 of file blocksort.c.

#define MAIN_QSORT_DEPTH_THRESH   (BZ_N_RADIX + BZ_N_QSORT)

Definition at line 619 of file blocksort.c.

#define MAIN_QSORT_SMALL_THRESH   20

Definition at line 618 of file blocksort.c.

#define MAIN_QSORT_STACK_SIZE   100

Definition at line 620 of file blocksort.c.

#define mmin (   a,
 
)    ((a) < (b)) ? (a) : (b)

Definition at line 596 of file blocksort.c.

#define mnextsize (   az)    (nextHi[az]-nextLo[az])

Definition at line 609 of file blocksort.c.

#define mnextswap (   az,
  bz 
)
Value:
{ Int32 tz; \
tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
int Int32
Definition: bzlib_private.h:46

Definition at line 611 of file blocksort.c.

#define mpop (   lz,
  hz,
  dz 
)
Value:
{ sp--; \
lz = stackLo[sp]; \
hz = stackHi[sp]; \
dz = stackD [sp]; }

Definition at line 603 of file blocksort.c.

#define mpush (   lz,
  hz,
  dz 
)
Value:
{ stackLo[sp] = lz; \
stackHi[sp] = hz; \
stackD [sp] = dz; \
sp++; }

Definition at line 598 of file blocksort.c.

#define mswap (   zz1,
  zz2 
)    { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }

Definition at line 569 of file blocksort.c.

#define mvswap (   zzp1,
  zzp2,
  zzn 
)
Value:
{ \
Int32 yyp1 = (zzp1); \
Int32 yyp2 = (zzp2); \
Int32 yyn = (zzn); \
while (yyn > 0) { \
mswap(ptr[yyp1], ptr[yyp2]); \
yyp1++; yyp2++; yyn--; \
} \
}
#define mswap(zz1, zz2)
Definition: blocksort.c:569
int Int32
Definition: bzlib_private.h:46

Definition at line 572 of file blocksort.c.

#define SET_BH (   zz)    bhtab[(zz) >> 5] |= (1 << ((zz) & 31))

Definition at line 207 of file blocksort.c.

#define SETMASK   (1 << 21)

Definition at line 749 of file blocksort.c.

#define UNALIGNED_BH (   zz)    ((zz) & 0x01f)

Definition at line 211 of file blocksort.c.

#define WORD_BH (   zz)    bhtab[(zz) >> 5]

Definition at line 210 of file blocksort.c.

Function Documentation

void BZ2_blockSort ( EState s)

Definition at line 1033 of file blocksort.c.

1034 {
1035  UInt32* ptr = s->ptr;
1036  UChar* block = s->block;
1037  UInt32* ftab = s->ftab;
1038  Int32 nblock = s->nblock;
1039  Int32 verb = s->verbosity;
1040  Int32 wfact = s->workFactor;
1041  UInt16* quadrant;
1042  Int32 budget;
1043  Int32 budgetInit;
1044  Int32 i;
1045 
1046  if (nblock < 10000) {
1047  fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1048  } else {
1049  /* Calculate the location for quadrant, remembering to get
1050  the alignment right. Assumes that &(block[0]) is at least
1051  2-byte aligned -- this should be ok since block is really
1052  the first section of arr2.
1053  */
1054  i = nblock+BZ_N_OVERSHOOT;
1055  if (i & 1) i++;
1056  quadrant = (UInt16*)(&(block[i]));
1057 
1058  /* (wfact-1) / 3 puts the default-factor-30
1059  transition point at very roughly the same place as
1060  with v0.1 and v0.9.0.
1061  Not that it particularly matters any more, since the
1062  resulting compressed stream is now the same regardless
1063  of whether or not we use the main sort or fallback sort.
1064  */
1065  if (wfact < 1 ) wfact = 1;
1066  if (wfact > 100) wfact = 100;
1067  budgetInit = nblock * ((wfact-1) / 3);
1068  budget = budgetInit;
1069 
1070  mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
1071  if (verb >= 3)
1072  VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
1073  budgetInit - budget,
1074  nblock,
1075  (float)(budgetInit - budget) /
1076  (float)(nblock==0 ? 1 : nblock) );
1077  if (budget < 0) {
1078  if (verb >= 2)
1079  VPrintf0 ( " too repetitive; using fallback"
1080  " sorting algorithm\n" );
1081  fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1082  }
1083  }
1084 
1085  s->origPtr = -1;
1086  for (i = 0; i < s->nblock; i++)
1087  if (ptr[i] == 0)
1088  { s->origPtr = i; break; };
1089 
1090  AssertH( s->origPtr != -1, 1003 );
1091 }
Int32 origPtr
Int32 workFactor
UInt32 * arr2
#define BZ_N_OVERSHOOT
#define AssertH(cond, errcode)
Definition: bzlib_private.h:61
Int32 verbosity
UInt32 * arr1
Int32 nblock
unsigned char UChar
Definition: bzlib_private.h:45
unsigned int UInt32
Definition: bzlib_private.h:47
UInt32 * ftab
#define VPrintf0(zf)
Definition: bzlib_private.h:75
int Int32
Definition: bzlib_private.h:46
#define VPrintf3(zf, za1, za2, za3)
Definition: bzlib_private.h:81
static void fallbackSort(UInt32 *fmap, UInt32 *eclass, UInt32 *bhtab, Int32 nblock, Int32 verb)
Definition: blocksort.c:214
UInt32 * ptr
UChar * block
unsigned short UInt16
Definition: bzlib_private.h:49
static void mainSort(UInt32 *ptr, UChar *block, UInt16 *quadrant, UInt32 *ftab, Int32 nblock, Int32 verb, Int32 *budget)
Definition: blocksort.c:753
static void fallbackQSort3 ( UInt32 fmap,
UInt32 eclass,
Int32  loSt,
Int32  hiSt 
)
static

Definition at line 95 of file blocksort.c.

99 {
100  Int32 unLo, unHi, ltLo, gtHi, n, m;
101  Int32 sp, lo, hi;
102  UInt32 med, r, r3;
105 
106  r = 0;
107 
108  sp = 0;
109  fpush ( loSt, hiSt );
110 
111  while (sp > 0) {
112 
113  AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
114 
115  fpop ( lo, hi );
116  if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
117  fallbackSimpleSort ( fmap, eclass, lo, hi );
118  continue;
119  }
120 
121  /* Random partitioning. Median of 3 sometimes fails to
122  avoid bad cases. Median of 9 seems to help but
123  looks rather expensive. This too seems to work but
124  is cheaper. Guidance for the magic constants
125  7621 and 32768 is taken from Sedgewick's algorithms
126  book, chapter 35.
127  */
128  r = ((r * 7621) + 1) % 32768;
129  r3 = r % 3;
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]];
133 
134  unLo = ltLo = lo;
135  unHi = gtHi = hi;
136 
137  while (1) {
138  while (1) {
139  if (unLo > unHi) break;
140  n = (Int32)eclass[fmap[unLo]] - (Int32)med;
141  if (n == 0) {
142  fswap(fmap[unLo], fmap[ltLo]);
143  ltLo++; unLo++;
144  continue;
145  };
146  if (n > 0) break;
147  unLo++;
148  }
149  while (1) {
150  if (unLo > unHi) break;
151  n = (Int32)eclass[fmap[unHi]] - (Int32)med;
152  if (n == 0) {
153  fswap(fmap[unHi], fmap[gtHi]);
154  gtHi--; unHi--;
155  continue;
156  };
157  if (n < 0) break;
158  unHi--;
159  }
160  if (unLo > unHi) break;
161  fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
162  }
163 
164  AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
165 
166  if (gtHi < ltLo) continue;
167 
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);
170 
171  n = lo + unLo - ltLo - 1;
172  m = hi - (gtHi - unHi) + 1;
173 
174  if (n - lo > hi - m) {
175  fpush ( lo, n );
176  fpush ( m, hi );
177  } else {
178  fpush ( m, hi );
179  fpush ( lo, n );
180  }
181  }
182 }
#define fpush(lz, hz)
Definition: blocksort.c:82
#define FALLBACK_QSORT_STACK_SIZE
Definition: blocksort.c:91
#define fpop(lz, hz)
Definition: blocksort.c:86
#define fmin(a, b)
Definition: blocksort.c:80
static ABC_NAMESPACE_IMPL_START __inline__ void fallbackSimpleSort(UInt32 *fmap, UInt32 *eclass, Int32 lo, Int32 hi)
Definition: blocksort.c:34
#define AssertH(cond, errcode)
Definition: bzlib_private.h:61
#define fswap(zz1, zz2)
Definition: blocksort.c:65
unsigned int UInt32
Definition: bzlib_private.h:47
#define fvswap(zzp1, zzp2, zzn)
Definition: blocksort.c:68
#define FALLBACK_QSORT_SMALL_THRESH
Definition: blocksort.c:90
int Int32
Definition: bzlib_private.h:46
#define AssertD(cond, msg)
Definition: bzlib_private.h:72
static ABC_NAMESPACE_IMPL_START __inline__ void fallbackSimpleSort ( UInt32 fmap,
UInt32 eclass,
Int32  lo,
Int32  hi 
)
static

Definition at line 34 of file blocksort.c.

38 {
39  Int32 i, j, tmp;
40  UInt32 ec_tmp;
41 
42  if (lo == hi) return;
43 
44  if (hi - lo > 3) {
45  for ( i = hi-4; i >= lo; i-- ) {
46  tmp = fmap[i];
47  ec_tmp = eclass[tmp];
48  for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
49  fmap[j-4] = fmap[j];
50  fmap[j-4] = tmp;
51  }
52  }
53 
54  for ( i = hi-1; i >= lo; i-- ) {
55  tmp = fmap[i];
56  ec_tmp = eclass[tmp];
57  for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
58  fmap[j-1] = fmap[j];
59  fmap[j-1] = tmp;
60  }
61 }
unsigned int UInt32
Definition: bzlib_private.h:47
int Int32
Definition: bzlib_private.h:46
static void fallbackSort ( UInt32 fmap,
UInt32 eclass,
UInt32 bhtab,
Int32  nblock,
Int32  verb 
)
static

Definition at line 214 of file blocksort.c.

219 {
220  Int32 ftab[257];
221  Int32 ftabCopy[256];
222  Int32 H, i, j, k, l, r, cc, cc1;
223  Int32 nNotDone;
224  Int32 nBhtab;
225  UChar* eclass8 = (UChar*)eclass;
226 
227  /*--
228  Initial 1-char radix sort to generate
229  initial fmap and initial BH bits.
230  --*/
231  if (verb >= 4)
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];
237 
238  for (i = 0; i < nblock; i++) {
239  j = eclass8[i];
240  k = ftab[j] - 1;
241  ftab[j] = k;
242  fmap[k] = i;
243  }
244 
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]);
248 
249  /*--
250  Inductively refine the buckets. Kind-of an
251  "exponential radix sort" (!), inspired by the
252  Manber-Myers suffix array construction algorithm.
253  --*/
254 
255  /*-- set sentinel bits for block-end detection --*/
256  for (i = 0; i < 32; i++) {
257  SET_BH(nblock + 2*i);
258  CLEAR_BH(nblock + 2*i + 1);
259  }
260 
261  /*-- the log(N) loop --*/
262  H = 1;
263  while (1) {
264 
265  if (verb >= 4)
266  VPrintf1 ( " depth %6d has ", H );
267 
268  j = 0;
269  for (i = 0; i < nblock; i++) {
270  if (ISSET_BH(i)) j = i;
271  k = fmap[i] - H; if (k < 0) k += nblock;
272  eclass[k] = j;
273  }
274 
275  nNotDone = 0;
276  r = -1;
277  while (1) {
278 
279  /*-- find the next non-singleton bucket --*/
280  k = r + 1;
281  while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
282  if (ISSET_BH(k)) {
283  while (WORD_BH(k) == 0xffffffff) k += 32;
284  while (ISSET_BH(k)) k++;
285  }
286  l = k - 1;
287  if (l >= nblock) break;
288  while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
289  if (!ISSET_BH(k)) {
290  while (WORD_BH(k) == 0x00000000) k += 32;
291  while (!ISSET_BH(k)) k++;
292  }
293  r = k - 1;
294  if (r >= nblock) break;
295 
296  /*-- now [l, r] bracket current bucket --*/
297  if (r > l) {
298  nNotDone += (r - l + 1);
299  fallbackQSort3 ( fmap, eclass, l, r );
300 
301  /*-- scan bucket and generate header bits-- */
302  cc = -1;
303  for (i = l; i <= r; i++) {
304  cc1 = eclass[fmap[i]];
305  if (cc != cc1) { SET_BH(i); cc = cc1; };
306  }
307  }
308  }
309 
310  if (verb >= 4)
311  VPrintf1 ( "%6d unresolved strings\n", nNotDone );
312 
313  H *= 2;
314  if (H > nblock || nNotDone == 0) break;
315  }
316 
317  /*--
318  Reconstruct the original block in
319  eclass8 [0 .. nblock-1], since the
320  previous phase destroyed it.
321  --*/
322  if (verb >= 4)
323  VPrintf0 ( " reconstructing block ...\n" );
324  j = 0;
325  for (i = 0; i < nblock; i++) {
326  while (ftabCopy[j] == 0) j++;
327  ftabCopy[j]--;
328  eclass8[fmap[i]] = (UChar)j;
329  }
330  AssertH ( j < 256, 1005 );
331 }
#define ISSET_BH(zz)
Definition: blocksort.c:209
#define UNALIGNED_BH(zz)
Definition: blocksort.c:211
#define VPrintf1(zf, za1)
Definition: bzlib_private.h:77
#define SET_BH(zz)
Definition: blocksort.c:207
#define AssertH(cond, errcode)
Definition: bzlib_private.h:61
unsigned char UChar
Definition: bzlib_private.h:45
#define WORD_BH(zz)
Definition: blocksort.c:210
#define CLEAR_BH(zz)
Definition: blocksort.c:208
#define VPrintf0(zf)
Definition: bzlib_private.h:75
int Int32
Definition: bzlib_private.h:46
static void fallbackQSort3(UInt32 *fmap, UInt32 *eclass, Int32 loSt, Int32 hiSt)
Definition: blocksort.c:95
static __inline__ Bool mainGtU ( UInt32  i1,
UInt32  i2,
UChar block,
UInt16 quadrant,
UInt32  nblock,
Int32 budget 
)
static

Definition at line 349 of file blocksort.c.

355 {
356  Int32 k;
357  UChar c1, c2;
358  UInt16 s1, s2;
359 
360  AssertD ( i1 != i2, "mainGtU" );
361  /* 1 */
362  c1 = block[i1]; c2 = block[i2];
363  if (c1 != c2) return (c1 > c2);
364  i1++; i2++;
365  /* 2 */
366  c1 = block[i1]; c2 = block[i2];
367  if (c1 != c2) return (c1 > c2);
368  i1++; i2++;
369  /* 3 */
370  c1 = block[i1]; c2 = block[i2];
371  if (c1 != c2) return (c1 > c2);
372  i1++; i2++;
373  /* 4 */
374  c1 = block[i1]; c2 = block[i2];
375  if (c1 != c2) return (c1 > c2);
376  i1++; i2++;
377  /* 5 */
378  c1 = block[i1]; c2 = block[i2];
379  if (c1 != c2) return (c1 > c2);
380  i1++; i2++;
381  /* 6 */
382  c1 = block[i1]; c2 = block[i2];
383  if (c1 != c2) return (c1 > c2);
384  i1++; i2++;
385  /* 7 */
386  c1 = block[i1]; c2 = block[i2];
387  if (c1 != c2) return (c1 > c2);
388  i1++; i2++;
389  /* 8 */
390  c1 = block[i1]; c2 = block[i2];
391  if (c1 != c2) return (c1 > c2);
392  i1++; i2++;
393  /* 9 */
394  c1 = block[i1]; c2 = block[i2];
395  if (c1 != c2) return (c1 > c2);
396  i1++; i2++;
397  /* 10 */
398  c1 = block[i1]; c2 = block[i2];
399  if (c1 != c2) return (c1 > c2);
400  i1++; i2++;
401  /* 11 */
402  c1 = block[i1]; c2 = block[i2];
403  if (c1 != c2) return (c1 > c2);
404  i1++; i2++;
405  /* 12 */
406  c1 = block[i1]; c2 = block[i2];
407  if (c1 != c2) return (c1 > c2);
408  i1++; i2++;
409 
410  k = nblock + 8;
411 
412  do {
413  /* 1 */
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);
418  i1++; i2++;
419  /* 2 */
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);
424  i1++; i2++;
425  /* 3 */
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);
430  i1++; i2++;
431  /* 4 */
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);
436  i1++; i2++;
437  /* 5 */
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);
442  i1++; i2++;
443  /* 6 */
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);
448  i1++; i2++;
449  /* 7 */
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);
454  i1++; i2++;
455  /* 8 */
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);
460  i1++; i2++;
461 
462  if (i1 >= nblock) i1 -= nblock;
463  if (i2 >= nblock) i2 -= nblock;
464 
465  k -= 8;
466  (*budget)--;
467  }
468  while (k >= 0);
469 
470  return False;
471 }
unsigned char UChar
Definition: bzlib_private.h:45
static char s1[largest_string]
Definition: set.c:514
int Int32
Definition: bzlib_private.h:46
#define AssertD(cond, msg)
Definition: bzlib_private.h:72
#define False
Definition: bzlib_private.h:52
unsigned short UInt16
Definition: bzlib_private.h:49
static void mainQSort3 ( UInt32 ptr,
UChar block,
UInt16 quadrant,
Int32  nblock,
Int32  loSt,
Int32  hiSt,
Int32  dSt,
Int32 budget 
)
static

Definition at line 623 of file blocksort.c.

631 {
632  Int32 unLo, unHi, ltLo, gtHi, n, m, med;
633  Int32 sp, lo, hi, d;
634 
635  Int32 stackLo[MAIN_QSORT_STACK_SIZE];
636  Int32 stackHi[MAIN_QSORT_STACK_SIZE];
637  Int32 stackD [MAIN_QSORT_STACK_SIZE];
638 
639  Int32 nextLo[3];
640  Int32 nextHi[3];
641  Int32 nextD [3];
642 
643  sp = 0;
644  mpush ( loSt, hiSt, dSt );
645 
646  while (sp > 0) {
647 
648  AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
649 
650  mpop ( lo, hi, d );
651  if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
653  mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
654  if (*budget < 0) return;
655  continue;
656  }
657 
658  med = (Int32)
659  mmed3 ( block[ptr[ lo ]+d],
660  block[ptr[ hi ]+d],
661  block[ptr[ (lo+hi)>>1 ]+d] );
662 
663  unLo = ltLo = lo;
664  unHi = gtHi = hi;
665 
666  while (True) {
667  while (True) {
668  if (unLo > unHi) break;
669  n = ((Int32)block[ptr[unLo]+d]) - med;
670  if (n == 0) {
671  mswap(ptr[unLo], ptr[ltLo]);
672  ltLo++; unLo++; continue;
673  };
674  if (n > 0) break;
675  unLo++;
676  }
677  while (True) {
678  if (unLo > unHi) break;
679  n = ((Int32)block[ptr[unHi]+d]) - med;
680  if (n == 0) {
681  mswap(ptr[unHi], ptr[gtHi]);
682  gtHi--; unHi--; continue;
683  };
684  if (n < 0) break;
685  unHi--;
686  }
687  if (unLo > unHi) break;
688  mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
689  }
690 
691  AssertD ( unHi == unLo-1, "mainQSort3(2)" );
692 
693  if (gtHi < ltLo) {
694  mpush(lo, hi, d+1 );
695  continue;
696  }
697 
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);
700 
701  n = lo + unLo - ltLo - 1;
702  m = hi - (gtHi - unHi) + 1;
703 
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;
707 
708  if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
709  if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
710  if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
711 
712  AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
713  AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
714 
715  mpush (nextLo[0], nextHi[0], nextD[0]);
716  mpush (nextLo[1], nextHi[1], nextD[1]);
717  mpush (nextLo[2], nextHi[2], nextD[2]);
718  }
719 }
#define MAIN_QSORT_SMALL_THRESH
Definition: blocksort.c:618
#define mswap(zz1, zz2)
Definition: blocksort.c:569
#define AssertH(cond, errcode)
Definition: bzlib_private.h:61
#define mpop(lz, hz, dz)
Definition: blocksort.c:603
#define mnextswap(az, bz)
Definition: blocksort.c:611
static __inline__ UChar mmed3(UChar a, UChar b, UChar c)
Definition: blocksort.c:585
#define mvswap(zzp1, zzp2, zzn)
Definition: blocksort.c:572
static void mainSimpleSort(UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 lo, Int32 hi, Int32 d, Int32 *budget)
Definition: blocksort.c:487
#define mmin(a, b)
Definition: blocksort.c:596
#define MAIN_QSORT_DEPTH_THRESH
Definition: blocksort.c:619
int Int32
Definition: bzlib_private.h:46
#define mpush(lz, hz, dz)
Definition: blocksort.c:598
#define AssertD(cond, msg)
Definition: bzlib_private.h:72
#define True
Definition: bzlib_private.h:51
#define MAIN_QSORT_STACK_SIZE
Definition: blocksort.c:620
#define mnextsize(az)
Definition: blocksort.c:609
static void mainSimpleSort ( UInt32 ptr,
UChar block,
UInt16 quadrant,
Int32  nblock,
Int32  lo,
Int32  hi,
Int32  d,
Int32 budget 
)
static

Definition at line 487 of file blocksort.c.

495 {
496  Int32 i, j, h, bigN, hp;
497  UInt32 v;
498 
499  bigN = hi - lo + 1;
500  if (bigN < 2) return;
501 
502  hp = 0;
503  while (incs[hp] < bigN) hp++;
504  hp--;
505 
506  for (; hp >= 0; hp--) {
507  h = incs[hp];
508 
509  i = lo + h;
510  while (True) {
511 
512  /*-- copy 1 --*/
513  if (i > hi) break;
514  v = ptr[i];
515  j = i;
516  while ( mainGtU (
517  ptr[j-h]+d, v+d, block, quadrant, nblock, budget
518  ) ) {
519  ptr[j] = ptr[j-h];
520  j = j - h;
521  if (j <= (lo + h - 1)) break;
522  }
523  ptr[j] = v;
524  i++;
525 
526  /*-- copy 2 --*/
527  if (i > hi) break;
528  v = ptr[i];
529  j = i;
530  while ( mainGtU (
531  ptr[j-h]+d, v+d, block, quadrant, nblock, budget
532  ) ) {
533  ptr[j] = ptr[j-h];
534  j = j - h;
535  if (j <= (lo + h - 1)) break;
536  }
537  ptr[j] = v;
538  i++;
539 
540  /*-- copy 3 --*/
541  if (i > hi) break;
542  v = ptr[i];
543  j = i;
544  while ( mainGtU (
545  ptr[j-h]+d, v+d, block, quadrant, nblock, budget
546  ) ) {
547  ptr[j] = ptr[j-h];
548  j = j - h;
549  if (j <= (lo + h - 1)) break;
550  }
551  ptr[j] = v;
552  i++;
553 
554  if (*budget < 0) return;
555  }
556  }
557 }
unsigned int UInt32
Definition: bzlib_private.h:47
int Int32
Definition: bzlib_private.h:46
#define True
Definition: bzlib_private.h:51
static Int32 incs[14]
Definition: blocksort.c:482
static __inline__ Bool mainGtU(UInt32 i1, UInt32 i2, UChar *block, UInt16 *quadrant, UInt32 nblock, Int32 *budget)
Definition: blocksort.c:349
static void mainSort ( UInt32 ptr,
UChar block,
UInt16 quadrant,
UInt32 ftab,
Int32  nblock,
Int32  verb,
Int32 budget 
)
static

Definition at line 753 of file blocksort.c.

760 {
761  Int32 i, j, k, ss, sb;
762  Int32 runningOrder[256];
763  Bool bigDone[256];
764  Int32 copyStart[256];
765  Int32 copyEnd [256];
766  UChar c1;
767  Int32 numQSorted;
768  UInt16 s;
769  if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
770 
771  /*-- set up the 2-byte frequency table --*/
772  for (i = 65536; i >= 0; i--) ftab[i] = 0;
773 
774  j = block[0] << 8;
775  i = nblock-1;
776  for (; i >= 3; i -= 4) {
777  quadrant[i] = 0;
778  j = (j >> 8) | ( ((UInt16)block[i]) << 8);
779  ftab[j]++;
780  quadrant[i-1] = 0;
781  j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
782  ftab[j]++;
783  quadrant[i-2] = 0;
784  j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
785  ftab[j]++;
786  quadrant[i-3] = 0;
787  j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
788  ftab[j]++;
789  }
790  for (; i >= 0; i--) {
791  quadrant[i] = 0;
792  j = (j >> 8) | ( ((UInt16)block[i]) << 8);
793  ftab[j]++;
794  }
795 
796  /*-- (emphasises close relationship of block & quadrant) --*/
797  for (i = 0; i < BZ_N_OVERSHOOT; i++) {
798  block [nblock+i] = block[i];
799  quadrant[nblock+i] = 0;
800  }
801 
802  if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
803 
804  /*-- Complete the initial radix sort --*/
805  for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
806 
807  s = block[0] << 8;
808  i = nblock-1;
809  for (; i >= 3; i -= 4) {
810  s = (s >> 8) | (block[i] << 8);
811  j = ftab[s] -1;
812  ftab[s] = j;
813  ptr[j] = i;
814  s = (s >> 8) | (block[i-1] << 8);
815  j = ftab[s] -1;
816  ftab[s] = j;
817  ptr[j] = i-1;
818  s = (s >> 8) | (block[i-2] << 8);
819  j = ftab[s] -1;
820  ftab[s] = j;
821  ptr[j] = i-2;
822  s = (s >> 8) | (block[i-3] << 8);
823  j = ftab[s] -1;
824  ftab[s] = j;
825  ptr[j] = i-3;
826  }
827  for (; i >= 0; i--) {
828  s = (s >> 8) | (block[i] << 8);
829  j = ftab[s] -1;
830  ftab[s] = j;
831  ptr[j] = i;
832  }
833 
834  /*--
835  Now ftab contains the first loc of every small bucket.
836  Calculate the running order, from smallest to largest
837  big bucket.
838  --*/
839  for (i = 0; i <= 255; i++) {
840  bigDone [i] = False;
841  runningOrder[i] = i;
842  }
843 
844  {
845  Int32 vv;
846  Int32 h = 1;
847  do h = 3 * h + 1; while (h <= 256);
848  do {
849  h = h / 3;
850  for (i = h; i <= 255; i++) {
851  vv = runningOrder[i];
852  j = i;
853  while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
854  runningOrder[j] = runningOrder[j-h];
855  j = j - h;
856  if (j <= (h - 1)) goto zero;
857  }
858  zero:
859  runningOrder[j] = vv;
860  }
861  } while (h != 1);
862  }
863 
864  /*--
865  The main sorting loop.
866  --*/
867 
868  numQSorted = 0;
869 
870  for (i = 0; i <= 255; i++) {
871 
872  /*--
873  Process big buckets, starting with the least full.
874  Basically this is a 3-step process in which we call
875  mainQSort3 to sort the small buckets [ss, j], but
876  also make a big effort to avoid the calls if we can.
877  --*/
878  ss = runningOrder[i];
879 
880  /*--
881  Step 1:
882  Complete the big bucket [ss] by quicksorting
883  any unsorted small buckets [ss, j], for j != ss.
884  Hopefully previous pointer-scanning phases have already
885  completed many of the small buckets [ss, j], so
886  we don't have to sort them at all.
887  --*/
888  for (j = 0; j <= 255; j++) {
889  if (j != ss) {
890  sb = (ss << 8) + j;
891  if ( ! (ftab[sb] & SETMASK) ) {
892  Int32 lo = ftab[sb] & CLEARMASK;
893  Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
894  if (hi > lo) {
895  if (verb >= 4)
896  VPrintf4 ( " qsort [0x%x, 0x%x] "
897  "done %d this %d\n",
898  ss, j, numQSorted, hi - lo + 1 );
899  mainQSort3 (
900  ptr, block, quadrant, nblock,
901  lo, hi, BZ_N_RADIX, budget
902  );
903  numQSorted += (hi - lo + 1);
904  if (*budget < 0) return;
905  }
906  }
907  ftab[sb] |= SETMASK;
908  }
909  }
910 
911  AssertH ( !bigDone[ss], 1006 );
912 
913  /*--
914  Step 2:
915  Now scan this big bucket [ss] so as to synthesise the
916  sorted order for small buckets [t, ss] for all t,
917  including, magically, the bucket [ss,ss] too.
918  This will avoid doing Real Work in subsequent Step 1's.
919  --*/
920  {
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;
924  }
925  for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
926  k = ptr[j]-1; if (k < 0) k += nblock;
927  c1 = block[k];
928  if (!bigDone[c1])
929  ptr[ copyStart[c1]++ ] = k;
930  }
931  for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
932  k = ptr[j]-1; if (k < 0) k += nblock;
933  c1 = block[k];
934  if (!bigDone[c1])
935  ptr[ copyEnd[c1]-- ] = k;
936  }
937  }
938 
939  AssertH ( (copyStart[ss]-1 == copyEnd[ss])
940  ||
941  /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
942  Necessity for this case is demonstrated by compressing
943  a sequence of approximately 48.5 million of character
944  251; 1.0.0/1.0.1 will then die here. */
945  (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
946  1007 )
947 
948  for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
949 
950  /*--
951  Step 3:
952  The [ss] big bucket is now done. Record this fact,
953  and update the quadrant descriptors. Remember to
954  update quadrants in the overshoot area too, if
955  necessary. The "if (i < 255)" test merely skips
956  this updating for the last bucket processed, since
957  updating for the last bucket is pointless.
958 
959  The quadrant array provides a way to incrementally
960  cache sort orderings, as they appear, so as to
961  make subsequent comparisons in fullGtU() complete
962  faster. For repetitive blocks this makes a big
963  difference (but not big enough to be able to avoid
964  the fallback sorting mechanism, exponential radix sort).
965 
966  The precise meaning is: at all times:
967 
968  for 0 <= i < nblock and 0 <= j <= nblock
969 
970  if block[i] != block[j],
971 
972  then the relative values of quadrant[i] and
973  quadrant[j] are meaningless.
974 
975  else {
976  if quadrant[i] < quadrant[j]
977  then the string starting at i lexicographically
978  precedes the string starting at j
979 
980  else if quadrant[i] > quadrant[j]
981  then the string starting at j lexicographically
982  precedes the string starting at i
983 
984  else
985  the relative ordering of the strings starting
986  at i and j has not yet been determined.
987  }
988  --*/
989  bigDone[ss] = True;
990 
991  if (i < 255) {
992  Int32 bbStart = ftab[ss << 8] & CLEARMASK;
993  Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
994  Int32 shifts = 0;
995 
996  while ((bbSize >> shifts) > 65534) shifts++;
997 
998  for (j = bbSize-1; j >= 0; j--) {
999  Int32 a2update = ptr[bbStart + j];
1000  UInt16 qVal = (UInt16)(j >> shifts);
1001  quadrant[a2update] = qVal;
1002  if (a2update < BZ_N_OVERSHOOT)
1003  quadrant[a2update + nblock] = qVal;
1004  }
1005  AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
1006  }
1007 
1008  }
1009 
1010  if (verb >= 4)
1011  VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
1012  nblock, numQSorted, nblock - numQSorted );
1013 }
#define BIGFREQ(b)
Definition: blocksort.c:748
unsigned char Bool
Definition: bzlib_private.h:44
#define BZ_N_OVERSHOOT
for(p=first;p->value< newval;p=p->next)
#define SETMASK
Definition: blocksort.c:749
#define BZ_N_RADIX
#define AssertH(cond, errcode)
Definition: bzlib_private.h:61
if(last==0)
Definition: sparse_int.h:34
unsigned char UChar
Definition: bzlib_private.h:45
#define VPrintf0(zf)
Definition: bzlib_private.h:75
int Int32
Definition: bzlib_private.h:46
#define VPrintf3(zf, za1, za2, za3)
Definition: bzlib_private.h:81
#define CLEARMASK
Definition: blocksort.c:750
#define True
Definition: bzlib_private.h:51
#define False
Definition: bzlib_private.h:52
unsigned short UInt16
Definition: bzlib_private.h:49
#define VPrintf4(zf, za1, za2, za3, za4)
Definition: bzlib_private.h:83
static void mainQSort3(UInt32 *ptr, UChar *block, UInt16 *quadrant, Int32 nblock, Int32 loSt, Int32 hiSt, Int32 dSt, Int32 *budget)
Definition: blocksort.c:623
static DdNode * zero
Definition: cuddApa.c:100
static __inline__ UChar mmed3 ( UChar  a,
UChar  b,
UChar  c 
)
static

Definition at line 585 of file blocksort.c.

586 {
587  UChar t;
588  if (a > b) { t = a; a = b; b = t; };
589  if (b > c) {
590  b = c;
591  if (a > b) b = a;
592  }
593  return b;
594 }
unsigned char UChar
Definition: bzlib_private.h:45

Variable Documentation

Int32 incs[14]
static
Initial value:
= { 1, 4, 13, 40, 121, 364, 1093, 3280,
9841, 29524, 88573, 265720,
797161, 2391484 }

Definition at line 482 of file blocksort.c.