diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2018-11-04 10:31:46 -0800 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2018-11-04 10:31:46 -0800 |
commit | 41d86c73b21191a3fa9ea5f476fc9f1fc5e4f8b3 (patch) | |
tree | ccb2cf4ee7f9f8713706d77dd8289178e2fbb7b1 /crc32.c | |
parent | 47cb41295751ee1b1b7e0acbfb847ea24324d5aa (diff) | |
download | zlib-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().
Diffstat (limited to 'crc32.c')
-rw-r--r-- | crc32.c | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -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) */ |
51 | local z_crc_t gf2_matrix_times OF((const z_crc_t *mat, z_crc_t vec)); | 51 | local z_crc_t gf2_matrix_times OF((const z_crc_t *mat, z_crc_t vec)); |
52 | local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); | 52 | local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); |
53 | local void crc32_combine_gen_ OF((z_crc_t *op, z_off64_t len2)); | ||
53 | 54 | ||
54 | /* ========================================================================= */ | 55 | /* ========================================================================= */ |
55 | local z_crc_t gf2_matrix_times(mat, vec) | 56 | local 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 | /* ========================================================================= */ | ||
458 | local 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 | /* ========================================================================= */ | ||
508 | void 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 | |||
515 | void 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 | /* ========================================================================= */ | ||
523 | uLong 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 | } | ||