File bzip2-faster.patch of Package bzip2
--- bzlib_private.h
+++ bzlib_private.h
@@ -340,6 +340,7 @@
#define MTFA_SIZE 4096
#define MTFL_SIZE 16
+#define HUFCODE_SIZE 10
/*-- Structure holding all the decompression-side stuff. --*/
@@ -407,6 +408,7 @@
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 minLens[BZ_N_GROUPS];
+ Int16 hufcode[BZ_N_GROUPS][1 << HUFCODE_SIZE];
/* save area for scalars in the main decompress code */
Int32 save_i;
@@ -433,6 +435,7 @@
Int32* save_gLimit;
Int32* save_gBase;
Int32* save_gPerm;
+ Int16* save_gHufCode;
}
DState;
@@ -488,8 +491,8 @@
BZ2_decompress ( DState* );
extern void
-BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
- Int32, Int32, Int32 );
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, Int16 *,
+ UChar*, Int32, Int32, Int32 );
#endif
--- decompress.c
+++ decompress.c
@@ -64,6 +64,9 @@
s->strm->total_in_hi32++; \
}
+#define UNGET_BITS(nnn) \
+ s->bsLive += nnn
+
#define GET_UCHAR(lll,uuu) \
GET_BITS(lll,uuu,8)
@@ -83,23 +86,29 @@
gLimit = &(s->limit[gSel][0]); \
gPerm = &(s->perm[gSel][0]); \
gBase = &(s->base[gSel][0]); \
+ gHufCode = &(s->hufcode[gSel][0]); \
} \
groupPos--; \
- zn = gMinlen; \
+ zn = HUFCODE_SIZE; \
GET_BITS(label1, zvec, zn); \
- while (1) { \
- if (zn > 20 /* the longest code */) \
- RETURN(BZ_DATA_ERROR); \
- if (zvec <= gLimit[zn]) break; \
- zn++; \
- GET_BIT(label2, zj); \
- zvec = (zvec << 1) | zj; \
- }; \
- if (zvec - gBase[zn] < 0 \
+ if (gHufCode[zvec]) { \
+ UNGET_BITS(gHufCode[zvec] >> 10); \
+ lval = gHufCode[zvec] & 511; \
+ } else { \
+ while (1) { \
+ if (zn > 20 /* the longest code */) \
+ RETURN(BZ_DATA_ERROR); \
+ if (zvec <= gLimit[zn]) break; \
+ zn++; \
+ GET_BIT(label2, zj); \
+ zvec = (zvec << 1) | zj; \
+ }; \
+ if (zvec - gBase[zn] < 0 \
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
- RETURN(BZ_DATA_ERROR); \
- lval = gPerm[zvec - gBase[zn]]; \
-}
+ RETURN(BZ_DATA_ERROR); \
+ lval = gPerm[zvec - gBase[zn]]; \
+ } \
+} \
/*---------------------------------------------------*/
@@ -135,6 +144,7 @@
Int32* gLimit;
Int32* gBase;
Int32* gPerm;
+ Int16* gHufCode;
if (s->state == BZ_X_MAGIC_1) {
/*initialise the save area*/
@@ -162,6 +172,7 @@
s->save_gLimit = NULL;
s->save_gBase = NULL;
s->save_gPerm = NULL;
+ s->save_gHufCode = NULL;
}
/*restore from the save area*/
@@ -189,6 +200,7 @@
gLimit = s->save_gLimit;
gBase = s->save_gBase;
gPerm = s->save_gPerm;
+ gHufCode = s->save_gHufCode;
retVal = BZ_OK;
@@ -340,6 +352,7 @@
&(s->limit[t][0]),
&(s->base[t][0]),
&(s->perm[t][0]),
+ &(s->hufcode[t][0]),
&(s->len[t][0]),
minLen, maxLen, alphaSize
);
@@ -414,6 +427,62 @@
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
/*-- uc = MTF ( nextSym-1 ) --*/
+#if MTFL_SIZE == 16
+ {
+ unsigned char *ppx = s->mtfa + s->mtfbase[0];
+ int lno = 0;
+
+ nextSym--;
+ if (nextSym >= MTFL_SIZE) {
+ lno = nextSym / MTFL_SIZE;
+ nextSym %= MTFL_SIZE;
+ ppx = s->mtfa + s->mtfbase[lno];
+ }
+ uc = ppx[nextSym];
+ switch(nextSym) {
+ case 9: ppx[9] = ppx[10];
+ case 10: ppx[10] = ppx[11];
+ case 11: ppx[11] = ppx[12];
+ case 12: ppx[12] = ppx[13];
+ case 13: ppx[13] = ppx[14];
+ case 14: ppx[14] = ppx[15];
+ case 15: goto copy;
+
+ case 8: ppx[8] = ppx[7];
+ case 7: ppx[7] = ppx[6];
+ case 6: ppx[6] = ppx[5];
+ case 5: ppx[5] = ppx[4];
+ case 4: ppx[4] = ppx[3];
+ case 3: ppx[3] = ppx[2];
+ case 2: ppx[2] = ppx[1];
+ case 1: ppx[1] = ppx[0];
+ default: break;
+ }
+ if (lno) {
+ s->mtfbase[lno]++;
+ copy:
+ while (lno > 0) {
+ s->mtfbase[lno]--;
+ s->mtfa[s->mtfbase[lno]] = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+ lno--;
+ }
+ s->mtfbase[0]--;
+ if (s->mtfbase[0] == 0) {
+ int ii, jj, kk;
+ s->mtfa[0] = uc;
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ }
+ s->mtfa[s->mtfbase[0]] = uc;
+ }
+#else
{
Int32 ii, jj, kk, pp, lno, off;
UInt32 nn;
@@ -465,6 +534,7 @@
}
}
}
+#endif
/*-- end uc = MTF ( nextSym-1 ) --*/
s->unzftab[s->seqToUnseq[uc]]++;
@@ -616,6 +686,7 @@
s->save_gLimit = gLimit;
s->save_gBase = gBase;
s->save_gPerm = gPerm;
+ s->save_gHufCode = gHufCode;
return retVal;
}
--- huffman.c
+++ huffman.c
@@ -173,13 +173,16 @@
void BZ2_hbCreateDecodeTables ( Int32 *limit,
Int32 *base,
Int32 *perm,
+ Int16 *hufcode,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
- Int32 pp, i, j, vec;
+ Int32 pp, i, j, vec, k, vec2;
+ for (i = 0; i < (1 << HUFCODE_SIZE); i++)
+ hufcode[i] = 0;
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (j = 0; j < alphaSize; j++)
@@ -190,16 +193,28 @@
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = -1;
vec = 0;
for (i = minLen; i <= maxLen; i++) {
+ if (i <= HUFCODE_SIZE) {
+ for (j = base[i]; j < base[i + 1]; j++) {
+ vec2 = (vec + j - base[i]) << (HUFCODE_SIZE - i);
+ k = (1 << (HUFCODE_SIZE - i));
+ if (vec2 + k > (1 << HUFCODE_SIZE))
+ k = (1 << HUFCODE_SIZE) - vec2;
+ for (; --k >= 0; vec2++)
+ hufcode[vec2] = perm[j] | 512 | (HUFCODE_SIZE - i) << 10;
+ }
+ }
vec += (base[i+1] - base[i]);
limit[i] = vec-1;
vec <<= 1;
}
for (i = minLen + 1; i <= maxLen; i++)
base[i] = ((limit[i-1] + 1) << 1) - base[i];
+ limit[maxLen + 1] = 0x7fffffff; /* make it terminate */
+ base[maxLen + 1] = 0;
}