summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2018-11-04 10:31:46 -0800
committerMark Adler <madler@alumni.caltech.edu>2018-11-04 10:31:46 -0800
commit41d86c73b21191a3fa9ea5f476fc9f1fc5e4f8b3 (patch)
treeccb2cf4ee7f9f8713706d77dd8289178e2fbb7b1
parent47cb41295751ee1b1b7e0acbfb847ea24324d5aa (diff)
downloadzlib-41d86c73b21191a3fa9ea5f476fc9f1fc5e4f8b3.tar.gz
zlib-41d86c73b21191a3fa9ea5f476fc9f1fc5e4f8b3.tar.bz2
zlib-41d86c73b21191a3fa9ea5f476fc9f1fc5e4f8b3.zip
Add crc32_combine_gen() and crc32_combine_op() for fast combines.
When the same len2 is used repeatedly, it is faster to use crc32_combine_gen() to generate an operator, that is then used to combine CRCs with crc32_combine_op().
-rw-r--r--crc32.c75
-rw-r--r--zlib.h22
2 files changed, 97 insertions, 0 deletions
diff --git a/crc32.c b/crc32.c
index 5ccfe09..2d213b3 100644
--- a/crc32.c
+++ b/crc32.c
@@ -50,6 +50,7 @@
50#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ 50#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
51local z_crc_t gf2_matrix_times OF((const z_crc_t *mat, z_crc_t vec)); 51local z_crc_t gf2_matrix_times OF((const z_crc_t *mat, z_crc_t vec));
52local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); 52local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
53local void crc32_combine_gen_ OF((z_crc_t *op, z_off64_t len2));
53 54
54/* ========================================================================= */ 55/* ========================================================================= */
55local z_crc_t gf2_matrix_times(mat, vec) 56local z_crc_t gf2_matrix_times(mat, vec)
@@ -452,3 +453,77 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
452{ 453{
453 return crc32_combine_(crc1, crc2, len2); 454 return crc32_combine_(crc1, crc2, len2);
454} 455}
456
457/* ========================================================================= */
458local void crc32_combine_gen_(op, len2)
459 z_crc_t *op;
460 z_off64_t len2;
461{
462 z_crc_t row;
463 int j;
464 unsigned i;
465
466#ifdef DYNAMIC_CRC_TABLE
467 if (crc_table_empty)
468 make_crc_table();
469#endif /* DYNAMIC_CRC_TABLE */
470
471 /* if len2 is zero or negative, return the identity matrix */
472 if (len2 <= 0) {
473 row = 1;
474 for (j = 0; j < GF2_DIM; j++) {
475 op[j] = row;
476 row <<= 1;
477 }
478 return;
479 }
480
481 /* at least one bit in len2 is set -- find it, and copy the operator
482 corresponding to that position into op */
483 i = 0;
484 for (;;) {
485 if (len2 & 1) {
486 for (j = 0; j < GF2_DIM; j++)
487 op[j] = crc_comb[i][j];
488 break;
489 }
490 len2 >>= 1;
491 i = (i + 1) % GF2_DIM;
492 }
493
494 /* for each remaining bit set in len2 (if any), multiply op by the operator
495 corresponding to that position */
496 for (;;) {
497 len2 >>= 1;
498 i = (i + 1) % GF2_DIM;
499 if (len2 == 0)
500 break;
501 if (len2 & 1)
502 for (j = 0; j < GF2_DIM; j++)
503 op[j] = gf2_matrix_times(crc_comb[i], op[j]);
504 }
505}
506
507/* ========================================================================= */
508void ZEXPORT crc32_combine_gen(op, len2)
509 z_crc_t *op;
510 z_off_t len2;
511{
512 crc32_combine_gen_(op, len2);
513}
514
515void ZEXPORT crc32_combine_gen64(op, len2)
516 z_crc_t *op;
517 z_off64_t len2;
518{
519 crc32_combine_gen_(op, len2);
520}
521
522/* ========================================================================= */
523uLong crc32_combine_op(crc1, crc2, op)
524 uLong crc1;
525 uLong crc2;
526 const z_crc_t *op;
527{
528 return gf2_matrix_times(op, crc1) ^ crc2;
529}
diff --git a/zlib.h b/zlib.h
index 0b74b25..14d87a2 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1757,6 +1757,22 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
1757 len2. 1757 len2.
1758*/ 1758*/
1759 1759
1760/*
1761ZEXTERN void ZEXPORT crc32_combine_gen OF((z_crc_t op[32], z_off_t len2));
1762
1763 Generate the operator op corresponding to length len2, to be used with
1764 crc32_combine_op(). op must have room for 32 z_crc_t values. (32 is the
1765 number of bits in the CRC.)
1766*/
1767
1768ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2,
1769 const z_crc_t *op));
1770/*
1771 Give the same result as crc32_combine(), using op in place of len2. op is
1772 is generated from len2 by crc32_combine_gen(). This will be faster than
1773 crc32_combine() if the generated op is used many times.
1774*/
1775
1760 1776
1761 /* various hacks, don't look :) */ 1777 /* various hacks, don't look :) */
1762 1778
@@ -1844,6 +1860,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
1844 ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); 1860 ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
1845 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); 1861 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
1846 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); 1862 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
1863 ZEXTERN void ZEXPORT crc32_combine_gen64 OF((z_crc_t *op, z_off64_t));
1847#endif 1864#endif
1848 1865
1849#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) 1866#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
@@ -1854,6 +1871,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
1854# define z_gzoffset z_gzoffset64 1871# define z_gzoffset z_gzoffset64
1855# define z_adler32_combine z_adler32_combine64 1872# define z_adler32_combine z_adler32_combine64
1856# define z_crc32_combine z_crc32_combine64 1873# define z_crc32_combine z_crc32_combine64
1874# define z_crc32_combine_gen z_crc32_combine64_gen
1857# else 1875# else
1858# define gzopen gzopen64 1876# define gzopen gzopen64
1859# define gzseek gzseek64 1877# define gzseek gzseek64
@@ -1861,6 +1879,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
1861# define gzoffset gzoffset64 1879# define gzoffset gzoffset64
1862# define adler32_combine adler32_combine64 1880# define adler32_combine adler32_combine64
1863# define crc32_combine crc32_combine64 1881# define crc32_combine crc32_combine64
1882# define crc32_combine_gen crc32_combine_gen64
1864# endif 1883# endif
1865# ifndef Z_LARGE64 1884# ifndef Z_LARGE64
1866 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); 1885 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
@@ -1869,6 +1888,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
1869 ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); 1888 ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
1870 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); 1889 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
1871 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); 1890 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
1891 ZEXTERN void ZEXPORT crc32_combine_gen64 OF((z_crc_t *op, z_off_t));
1872# endif 1892# endif
1873#else 1893#else
1874 ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); 1894 ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
@@ -1877,12 +1897,14 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
1877 ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); 1897 ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
1878 ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); 1898 ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
1879 ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); 1899 ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
1900 ZEXTERN void ZEXPORT crc32_combine_gen OF((z_crc_t *op, z_off_t));
1880#endif 1901#endif
1881 1902
1882#else /* Z_SOLO */ 1903#else /* Z_SOLO */
1883 1904
1884 ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); 1905 ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
1885 ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); 1906 ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
1907 ZEXTERN void ZEXPORT crc32_combine_gen OF((z_crc_t *op, z_off_t));
1886 1908
1887#endif /* !Z_SOLO */ 1909#endif /* !Z_SOLO */
1888 1910