XRootD
Loading...
Searching...
No Matches
XrdOucCRC32C.hh File Reference
#include <cstddef>
#include <cstdint>
Include dependency graph for XrdOucCRC32C.hh:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

uint32_t crc32c (uint32_t crc, void const *buf, size_t len)
uint32_t crc32c_combine (uint32_t crcA, uint32_t crcB, size_t lengthB)
 merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA))
uint32_t crc32c_sw (uint32_t crc, void const *buf, size_t len)

Function Documentation

◆ crc32c()

uint32_t crc32c ( uint32_t crc,
void const * buf,
size_t len )

Definition at line 277 of file XrdOucCRC32C.cc.

277 {
278 return crc32c_sw(crc, buf, len);
279}
uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len)

References crc32c(), and crc32c_sw().

Referenced by XrdEc::ObjCfg::ObjCfg(), XrdOucCRC::Calc32C(), XrdOucCRC::Calc32C(), XrdPfc::Info::CalcCksumStore(), XrdPfc::Info::CalcCksumSyncedAndAStats(), crc32c(), XrdOssCsiPages::FetchRangeUnaligned_postblock(), XrdOssCsiPages::FetchRangeUnaligned_preblock(), XrdOssCsiPages::StoreRangeUnaligned_postblock(), XrdOssCsiPages::StoreRangeUnaligned_preblock(), XrdOssCsiPages::truncate(), XrdOssCsiPages::UpdateRangeHoleUntilPage(), XrdOucCRC::Ver32C(), XrdOucCRC::Ver32C(), XrdOucCRC::Ver32C(), and XrdOucCRC::Ver32C().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ crc32c_combine()

uint32_t crc32c_combine ( uint32_t crcA,
uint32_t crcB,
size_t lengthB )

merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA))

CRC32 => 32 bits

Definition at line 437 of file XrdOucCRC32C.cc.

438{
439 // Original source from Stephan Brumme
440 // https://github.com/stbrumme/crc32
441 // https://create.stephan-brumme.com/crc32/
442 // based on Mark Adler's crc_combine from
443 // https://github.com/madler/pigz/blob/master/pigz.c
444
445 // main idea:
446 // - if you have two equally-sized blocks A and B,
447 // then you can create a block C = A ^ B
448 // which has the property crc(C) = crc(A) ^ crc(B)
449 // - if you append length(B) zeros to A and call it A' (think of it as AAAA000)
450 // and prepend length(A) zeros to B and call it B' (think of it as 0000BBB)
451 // then exists a C' = A' ^ B'
452 // - remember: if you XOR someting with zero, it remains unchanged: X ^ 0 = X
453 // - that means C' = A concat B so that crc(A concat B) = crc(C') = crc(A') ^ crc(B')
454 // - the trick is to compute crc(A') based on crc(A)
455 // and crc(B') based on crc(B)
456 // - since B' starts with many zeros, the crc of those initial zeros is still zero
457 // - that means crc(B') = crc(B)
458 // - unfortunately the trailing zeros of A' change the crc, so usually crc(A') != crc(A)
459 // - the following code is a fast algorithm to compute crc(A')
460 // - starting with crc(A) and appending length(B) zeros, needing just log2(length(B)) iterations
461 // - the details are explained by the original author at
462 // https://stackoverflow.com/questions/23122312/crc-calculation-of-a-mostly-static-data-stream/23126768
463 //
464 // notes:
465 // - I squeezed everything into one function to keep global namespace clean (original code two helper functions)
466 // - most original comments are still in place, I added comments where these helper functions where made inline code
467 // - performance-wise there isn't any differenze to the original zlib/pigz code
468
469 // degenerated case
470 if (lengthB == 0)
471 return crcA;
472
474 const uint32_t CrcBits = 32;
475
476 uint32_t odd [CrcBits]; // odd-power-of-two zeros operator
477 uint32_t even[CrcBits]; // even-power-of-two zeros operator
478
479 // put operator for one zero bit in odd
480 odd[0] = POLY; // CRC-32 polynomial
481 for (int i = 1; i < (int)CrcBits; i++)
482 odd[i] = 1 << (i - 1);
483
484 // put operator for two zero bits in even
485 // same as gf2_matrix_square(even, odd);
486 for (int i = 0; i < (int)CrcBits; i++)
487 {
488 uint32_t vec = odd[i];
489 even[i] = 0;
490 for (int j = 0; vec != 0; j++, vec >>= 1)
491 if (vec & 1)
492 even[i] ^= odd[j];
493 }
494 // put operator for four zero bits in odd
495 // same as gf2_matrix_square(odd, even);
496 for (int i = 0; i < (int)CrcBits; i++)
497 {
498 uint32_t vec = even[i];
499 odd[i] = 0;
500 for (int j = 0; vec != 0; j++, vec >>= 1)
501 if (vec & 1)
502 odd[i] ^= even[j];
503 }
504
505 // the following loop becomes much shorter if I keep swapping even and odd
506 uint32_t* a = even;
507 uint32_t* b = odd;
508 // apply secondLength zeros to firstCrc32
509 for (; lengthB > 0; lengthB >>= 1)
510 {
511 // same as gf2_matrix_square(a, b);
512 for (int i = 0; i < (int)CrcBits; i++)
513 {
514 uint32_t vec = b[i];
515 a[i] = 0;
516 for (int j = 0; vec != 0; j++, vec >>= 1)
517 if (vec & 1)
518 a[i] ^= b[j];
519 }
520
521 // apply zeros operator for this bit
522 if (lengthB & 1)
523 {
524 // same as firstCrc32 = gf2_matrix_times(a, firstCrc32);
525 uint32_t sum = 0;
526 for (int i = 0; crcA != 0; i++, crcA >>= 1)
527 if (crcA & 1)
528 sum ^= a[i];
529 crcA = sum;
530 }
531
532 // switch even and odd
533 uint32_t* t = a; a = b; b = t;
534 }
535
536 // return combined crc
537 return crcA ^ crcB;
538}
#define POLY

References crc32c_combine(), and POLY.

Referenced by XrdOucCRC::Combine32C(), and crc32c_combine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ crc32c_sw()

uint32_t crc32c_sw ( uint32_t crc,
void const * buf,
size_t len )

Definition at line 424 of file XrdOucCRC32C.cc.

424 {
425 static int const little = 1;
426 if (*(char const *)&little)
427 return crc32c_sw_little(crc, buf, len);
428 else
429 return crc32c_sw_big(crc, buf, len);
430}
uint32_t crc32c_sw_big(uint32_t crc, void const *buf, size_t len)
uint32_t crc32c_sw_little(uint32_t crc, void const *buf, size_t len)

References crc32c_sw(), crc32c_sw_big(), and crc32c_sw_little().

Referenced by crc32c(), and crc32c_sw().

Here is the call graph for this function:
Here is the caller graph for this function: