关键词搜索

源码搜索 ×
×

漫话Redis源码之十六

发布2021-11-28浏览530次

详情内容

你看Redis源码,真的高绿很周到,各种CPU模式都考虑到了,兼容性特别强。咱们平时做代码开发,也需要考虑通用性。

  1. /* Test of the CPU is Little Endian and supports not aligned accesses.
  2. * Two interesting conditions to speedup the function that happen to be
  3. * in most of x86 servers. */
  4. #if defined(__X86_64__) || defined(__x86_64__) || defined (__i386__) \
  5. || defined (__aarch64__) || defined (__arm64__)
  6. #define UNALIGNED_LE_CPU
  7. #endif
  8. #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
  9. #define U32TO8_LE(p, v) \
  10. (p)[0] = (uint8_t)((v)); \
  11. (p)[1] = (uint8_t)((v) >> 8); \
  12. (p)[2] = (uint8_t)((v) >> 16); \
  13. (p)[3] = (uint8_t)((v) >> 24);
  14. #define U64TO8_LE(p, v) \
  15. U32TO8_LE((p), (uint32_t)((v))); \
  16. U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
  17. #ifdef UNALIGNED_LE_CPU
  18. #define U8TO64_LE(p) (*((uint64_t*)(p)))
  19. #else
  20. #define U8TO64_LE(p) \
  21. (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
  22. ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
  23. ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
  24. ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
  25. #endif
  26. #define U8TO64_LE_NOCASE(p) \
  27. (((uint64_t)(siptlw((p)[0]))) | \
  28. ((uint64_t)(siptlw((p)[1])) << 8) | \
  29. ((uint64_t)(siptlw((p)[2])) << 16) | \
  30. ((uint64_t)(siptlw((p)[3])) << 24) | \
  31. ((uint64_t)(siptlw((p)[4])) << 32) | \
  32. ((uint64_t)(siptlw((p)[5])) << 40) | \
  33. ((uint64_t)(siptlw((p)[6])) << 48) | \
  34. ((uint64_t)(siptlw((p)[7])) << 56))
  35. #define SIPROUND \
  36. do { \
  37. v0 += v1; \
  38. v1 = ROTL(v1, 13); \
  39. v1 ^= v0; \
  40. v0 = ROTL(v0, 32); \
  41. v2 += v3; \
  42. v3 = ROTL(v3, 16); \
  43. v3 ^= v2; \
  44. v0 += v3; \
  45. v3 = ROTL(v3, 21); \
  46. v3 ^= v0; \
  47. v2 += v1; \
  48. v1 = ROTL(v1, 17); \
  49. v1 ^= v2; \
  50. v2 = ROTL(v2, 32); \
  51. } while (0)
  52. uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) {
  53. #ifndef UNALIGNED_LE_CPU
  54. uint64_t hash;
  55. uint8_t *out = (uint8_t*) &hash;
  56. #endif
  57. uint64_t v0 = 0x736f6d6570736575ULL;
  58. uint64_t v1 = 0x646f72616e646f6dULL;
  59. uint64_t v2 = 0x6c7967656e657261ULL;
  60. uint64_t v3 = 0x7465646279746573ULL;
  61. uint64_t k0 = U8TO64_LE(k);
  62. uint64_t k1 = U8TO64_LE(k + 8);
  63. uint64_t m;
  64. const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
  65. const int left = inlen & 7;
  66. uint64_t b = ((uint64_t)inlen) << 56;
  67. v3 ^= k1;
  68. v2 ^= k0;
  69. v1 ^= k1;
  70. v0 ^= k0;
  71. for (; in != end; in += 8) {
  72. m = U8TO64_LE(in);
  73. v3 ^= m;
  74. SIPROUND;
  75. v0 ^= m;
  76. }
  77. switch (left) {
  78. case 7: b |= ((uint64_t)in[6]) << 48; /* fall-thru */
  79. case 6: b |= ((uint64_t)in[5]) << 40; /* fall-thru */
  80. case 5: b |= ((uint64_t)in[4]) << 32; /* fall-thru */
  81. case 4: b |= ((uint64_t)in[3]) << 24; /* fall-thru */
  82. case 3: b |= ((uint64_t)in[2]) << 16; /* fall-thru */
  83. case 2: b |= ((uint64_t)in[1]) << 8; /* fall-thru */
  84. case 1: b |= ((uint64_t)in[0]); break;
  85. case 0: break;
  86. }
  87. v3 ^= b;
  88. SIPROUND;
  89. v0 ^= b;
  90. v2 ^= 0xff;
  91. SIPROUND;
  92. SIPROUND;
  93. b = v0 ^ v1 ^ v2 ^ v3;
  94. #ifndef UNALIGNED_LE_CPU
  95. U64TO8_LE(out, b);
  96. return hash;
  97. #else
  98. return b;
  99. #endif
  100. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载