hash_composite_inc.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* NOLINT(build/header_guard) */
  2. /* Copyright 2018 Google Inc. All Rights Reserved.
  3. Distributed under MIT license.
  4. See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
  5. */
  6. /* template parameters: FN, HASHER_A, HASHER_B */
  7. /* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
  8. and HASHER_B. */
  9. #define HashComposite HASHER()
  10. #define FN_A(X) EXPAND_CAT(X, HASHER_A)
  11. #define FN_B(X) EXPAND_CAT(X, HASHER_B)
  12. static BROTLI_INLINE size_t FN(HashTypeLength)(void) {
  13. size_t a = FN_A(HashTypeLength)();
  14. size_t b = FN_B(HashTypeLength)();
  15. return a > b ? a : b;
  16. }
  17. static BROTLI_INLINE size_t FN(StoreLookahead)(void) {
  18. size_t a = FN_A(StoreLookahead)();
  19. size_t b = FN_B(StoreLookahead)();
  20. return a > b ? a : b;
  21. }
  22. typedef struct HashComposite {
  23. HASHER_A ha;
  24. HASHER_B hb;
  25. HasherCommon ha_common;
  26. HasherCommon hb_common;
  27. /* Shortcuts. */
  28. HasherCommon* common;
  29. BROTLI_BOOL fresh;
  30. const BrotliEncoderParams* params;
  31. } HashComposite;
  32. static void FN(Initialize)(HasherCommon* common,
  33. HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) {
  34. self->common = common;
  35. self->ha_common = *self->common;
  36. self->hb_common = *self->common;
  37. self->fresh = BROTLI_TRUE;
  38. self->params = params;
  39. /* TODO(lode): Initialize of the hashers is deferred to Prepare (and params
  40. remembered here) because we don't get the one_shot and input_size params
  41. here that are needed to know the memory size of them. Instead provide
  42. those params to all hashers FN(Initialize) */
  43. }
  44. static void FN(Prepare)(
  45. HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
  46. size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
  47. if (self->fresh) {
  48. self->fresh = BROTLI_FALSE;
  49. self->ha_common.extra[0] = self->common->extra[0];
  50. self->ha_common.extra[1] = self->common->extra[1];
  51. self->ha_common.extra[2] = NULL;
  52. self->ha_common.extra[3] = NULL;
  53. self->hb_common.extra[0] = self->common->extra[2];
  54. self->hb_common.extra[1] = self->common->extra[3];
  55. self->hb_common.extra[2] = NULL;
  56. self->hb_common.extra[3] = NULL;
  57. FN_A(Initialize)(&self->ha_common, &self->ha, self->params);
  58. FN_B(Initialize)(&self->hb_common, &self->hb, self->params);
  59. }
  60. FN_A(Prepare)(&self->ha, one_shot, input_size, data);
  61. FN_B(Prepare)(&self->hb, one_shot, input_size, data);
  62. }
  63. static BROTLI_INLINE void FN(HashMemAllocInBytes)(
  64. const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
  65. size_t input_size, size_t* alloc_size) {
  66. size_t alloc_size_a[4] = {0};
  67. size_t alloc_size_b[4] = {0};
  68. FN_A(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_a);
  69. FN_B(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_b);
  70. /* Should never happen. */
  71. if (alloc_size_a[2] != 0 || alloc_size_a[3] != 0) exit(EXIT_FAILURE);
  72. if (alloc_size_b[2] != 0 || alloc_size_b[3] != 0) exit(EXIT_FAILURE);
  73. alloc_size[0] = alloc_size_a[0];
  74. alloc_size[1] = alloc_size_a[1];
  75. alloc_size[2] = alloc_size_b[0];
  76. alloc_size[3] = alloc_size_b[1];
  77. }
  78. static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self,
  79. const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
  80. FN_A(Store)(&self->ha, data, mask, ix);
  81. FN_B(Store)(&self->hb, data, mask, ix);
  82. }
  83. static BROTLI_INLINE void FN(StoreRange)(
  84. HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
  85. const size_t mask, const size_t ix_start,
  86. const size_t ix_end) {
  87. FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end);
  88. FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end);
  89. }
  90. static BROTLI_INLINE void FN(StitchToPreviousBlock)(
  91. HashComposite* BROTLI_RESTRICT self,
  92. size_t num_bytes, size_t position, const uint8_t* ringbuffer,
  93. size_t ring_buffer_mask) {
  94. FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position,
  95. ringbuffer, ring_buffer_mask);
  96. FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position,
  97. ringbuffer, ring_buffer_mask);
  98. }
  99. static BROTLI_INLINE void FN(PrepareDistanceCache)(
  100. HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) {
  101. FN_A(PrepareDistanceCache)(&self->ha, distance_cache);
  102. FN_B(PrepareDistanceCache)(&self->hb, distance_cache);
  103. }
  104. static BROTLI_INLINE void FN(FindLongestMatch)(
  105. HashComposite* BROTLI_RESTRICT self,
  106. const BrotliEncoderDictionary* dictionary,
  107. const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
  108. const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
  109. const size_t max_length, const size_t max_backward,
  110. const size_t dictionary_distance, const size_t max_distance,
  111. HasherSearchResult* BROTLI_RESTRICT out) {
  112. FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask,
  113. distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
  114. max_distance, out);
  115. FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask,
  116. distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
  117. max_distance, out);
  118. }
  119. #undef HashComposite