block_chain.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "stdafx.h"
  2. #include "block_chain.h"
  3. #include <util/system/unaligned_mem.h>
  4. namespace NNetliba {
  5. ui32 CalcChecksum(const void* p, int size) {
  6. //return 0;
  7. //return CalcCrc32(p, size);
  8. i64 sum = 0;
  9. const unsigned char *pp = (const unsigned char*)p, *pend = pp + size;
  10. for (const unsigned char* pend4 = pend - 3; pp < pend4; pp += 4)
  11. sum += *(const ui32*)pp;
  12. ui32 left = 0, pos = 0;
  13. for (; pp < pend; ++pp) {
  14. pos += ((ui32)*pp) << left;
  15. left += 8;
  16. }
  17. sum += pos;
  18. sum = (sum & 0xffffffff) + (sum >> 32);
  19. sum += sum >> 32;
  20. return (ui32)~sum;
  21. }
  22. ui32 CalcChecksum(const TBlockChain& chain) {
  23. TIncrementalChecksumCalcer ics;
  24. AddChain(&ics, chain);
  25. return ics.CalcChecksum();
  26. }
  27. void TIncrementalChecksumCalcer::AddBlock(const void* p, int size) {
  28. ui32 sum = CalcBlockSum(p, size);
  29. AddBlockSum(sum, size);
  30. }
  31. void TIncrementalChecksumCalcer::AddBlockSum(ui32 sum, int size) {
  32. for (int k = 0; k < Offset; ++k)
  33. sum = (sum >> 24) + ((sum & 0xffffff) << 8);
  34. TotalSum += sum;
  35. Offset = (Offset + size) & 3;
  36. }
  37. ui32 TIncrementalChecksumCalcer::CalcBlockSum(const void* p, int size) {
  38. i64 sum = 0;
  39. const unsigned char *pp = (const unsigned char*)p, *pend = pp + size;
  40. for (const unsigned char* pend4 = pend - 3; pp < pend4; pp += 4)
  41. sum += ReadUnaligned<ui32>(pp);
  42. ui32 left = 0, pos = 0;
  43. for (; pp < pend; ++pp) {
  44. pos += ((ui32)*pp) << left;
  45. left += 8;
  46. }
  47. sum += pos;
  48. sum = (sum & 0xffffffff) + (sum >> 32);
  49. sum += sum >> 32;
  50. return (ui32)sum;
  51. }
  52. ui32 TIncrementalChecksumCalcer::CalcChecksum() {
  53. TotalSum = (TotalSum & 0xffffffff) + (TotalSum >> 32);
  54. TotalSum += TotalSum >> 32;
  55. return (ui32)~TotalSum;
  56. }
  57. //void TestChainChecksum()
  58. //{
  59. // TVector<char> data;
  60. // data.resize(10);
  61. // for (int i = 0; i < data.ysize(); ++i)
  62. // data[i] = rand();
  63. // int crc1 = CalcChecksum(&data[0], data.size());
  64. //
  65. // TBlockChain chain;
  66. // TIncrementalChecksumCalcer incCS;
  67. // for (int offset = 0; offset < data.ysize();) {
  68. // int sz = Min(rand() % 10, data.ysize() - offset);
  69. // chain.AddBlock(&data[offset], sz);
  70. // incCS.AddBlock(&data[offset], sz);
  71. // offset += sz;
  72. // }
  73. // int crc2 = CalcChecksum(chain);
  74. // Y_ASSERT(crc1 == crc2);
  75. // int crc3 = incCS.CalcChecksum();
  76. // Y_ASSERT(crc1 == crc3);
  77. //}
  78. }