126fa459cSmrg/* NOLINT(build/header_guard) */
226fa459cSmrg/* Copyright 2018 Google Inc. All Rights Reserved.
326fa459cSmrg
426fa459cSmrg   Distributed under MIT license.
526fa459cSmrg   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
626fa459cSmrg*/
726fa459cSmrg
826fa459cSmrg/* template parameters: FN, HASHER_A, HASHER_B */
926fa459cSmrg
1026fa459cSmrg/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A
1126fa459cSmrg   and HASHER_B. */
1226fa459cSmrg
1326fa459cSmrg#define HashComposite HASHER()
1426fa459cSmrg
1526fa459cSmrg#define FN_A(X) EXPAND_CAT(X, HASHER_A)
1626fa459cSmrg#define FN_B(X) EXPAND_CAT(X, HASHER_B)
1726fa459cSmrg
1826fa459cSmrgstatic BROTLI_INLINE size_t FN(HashTypeLength)(void) {
1926fa459cSmrg  size_t a =  FN_A(HashTypeLength)();
2026fa459cSmrg  size_t b =  FN_B(HashTypeLength)();
2126fa459cSmrg  return a > b ? a : b;
2226fa459cSmrg}
2326fa459cSmrg
2426fa459cSmrgstatic BROTLI_INLINE size_t FN(StoreLookahead)(void) {
2526fa459cSmrg  size_t a =  FN_A(StoreLookahead)();
2626fa459cSmrg  size_t b =  FN_B(StoreLookahead)();
2726fa459cSmrg  return a > b ? a : b;
2826fa459cSmrg}
2926fa459cSmrg
3026fa459cSmrgtypedef struct HashComposite {
3126fa459cSmrg  HASHER_A ha;
3226fa459cSmrg  HASHER_B hb;
3326fa459cSmrg  HasherCommon hb_common;
3426fa459cSmrg
3526fa459cSmrg  /* Shortcuts. */
3626fa459cSmrg  void* extra;
3726fa459cSmrg  HasherCommon* common;
3826fa459cSmrg
3926fa459cSmrg  BROTLI_BOOL fresh;
4026fa459cSmrg  const BrotliEncoderParams* params;
4126fa459cSmrg} HashComposite;
4226fa459cSmrg
4326fa459cSmrgstatic void FN(Initialize)(HasherCommon* common,
4426fa459cSmrg    HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) {
4526fa459cSmrg  self->common = common;
4626fa459cSmrg  self->extra = common->extra;
4726fa459cSmrg
4826fa459cSmrg  self->hb_common = *self->common;
4926fa459cSmrg  self->fresh = BROTLI_TRUE;
5026fa459cSmrg  self->params = params;
5126fa459cSmrg  /* TODO: Initialize of the hashers is defered to Prepare (and params
5226fa459cSmrg     remembered here) because we don't get the one_shot and input_size params
5326fa459cSmrg     here that are needed to know the memory size of them. Instead provide
5426fa459cSmrg     those params to all hashers FN(Initialize) */
5526fa459cSmrg}
5626fa459cSmrg
5726fa459cSmrgstatic void FN(Prepare)(
5826fa459cSmrg    HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
5926fa459cSmrg    size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
6026fa459cSmrg  if (self->fresh) {
6126fa459cSmrg    self->fresh = BROTLI_FALSE;
6226fa459cSmrg    self->hb_common.extra = (uint8_t*)self->extra +
6326fa459cSmrg        FN_A(HashMemAllocInBytes)(self->params, one_shot, input_size);
6426fa459cSmrg
6526fa459cSmrg    FN_A(Initialize)(self->common, &self->ha, self->params);
6626fa459cSmrg    FN_B(Initialize)(&self->hb_common, &self->hb, self->params);
6726fa459cSmrg  }
6826fa459cSmrg  FN_A(Prepare)(&self->ha, one_shot, input_size, data);
6926fa459cSmrg  FN_B(Prepare)(&self->hb, one_shot, input_size, data);
7026fa459cSmrg}
7126fa459cSmrg
7226fa459cSmrgstatic BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
7326fa459cSmrg    const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
7426fa459cSmrg    size_t input_size) {
7526fa459cSmrg  return FN_A(HashMemAllocInBytes)(params, one_shot, input_size) +
7626fa459cSmrg      FN_B(HashMemAllocInBytes)(params, one_shot, input_size);
7726fa459cSmrg}
7826fa459cSmrg
7926fa459cSmrgstatic BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self,
8026fa459cSmrg    const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) {
8126fa459cSmrg  FN_A(Store)(&self->ha, data, mask, ix);
8226fa459cSmrg  FN_B(Store)(&self->hb, data, mask, ix);
8326fa459cSmrg}
8426fa459cSmrg
8526fa459cSmrgstatic BROTLI_INLINE void FN(StoreRange)(
8626fa459cSmrg    HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
8726fa459cSmrg    const size_t mask, const size_t ix_start,
8826fa459cSmrg    const size_t ix_end) {
8926fa459cSmrg  FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end);
9026fa459cSmrg  FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end);
9126fa459cSmrg}
9226fa459cSmrg
9326fa459cSmrgstatic BROTLI_INLINE void FN(StitchToPreviousBlock)(
9426fa459cSmrg    HashComposite* BROTLI_RESTRICT self,
9526fa459cSmrg    size_t num_bytes, size_t position, const uint8_t* ringbuffer,
9626fa459cSmrg    size_t ring_buffer_mask) {
9726fa459cSmrg  FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position,
9826fa459cSmrg      ringbuffer, ring_buffer_mask);
9926fa459cSmrg  FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position,
10026fa459cSmrg      ringbuffer, ring_buffer_mask);
10126fa459cSmrg}
10226fa459cSmrg
10326fa459cSmrgstatic BROTLI_INLINE void FN(PrepareDistanceCache)(
10426fa459cSmrg    HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) {
10526fa459cSmrg  FN_A(PrepareDistanceCache)(&self->ha, distance_cache);
10626fa459cSmrg  FN_B(PrepareDistanceCache)(&self->hb, distance_cache);
10726fa459cSmrg}
10826fa459cSmrg
10926fa459cSmrgstatic BROTLI_INLINE void FN(FindLongestMatch)(
11026fa459cSmrg    HashComposite* BROTLI_RESTRICT self,
11126fa459cSmrg    const BrotliEncoderDictionary* dictionary,
11226fa459cSmrg    const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
11326fa459cSmrg    const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
11426fa459cSmrg    const size_t max_length, const size_t max_backward,
11526fa459cSmrg    const size_t dictionary_distance, const size_t max_distance,
11626fa459cSmrg    HasherSearchResult* BROTLI_RESTRICT out) {
11726fa459cSmrg  FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask,
11826fa459cSmrg      distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
11926fa459cSmrg      max_distance, out);
12026fa459cSmrg  FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask,
12126fa459cSmrg      distance_cache, cur_ix, max_length, max_backward, dictionary_distance,
12226fa459cSmrg      max_distance, out);
12326fa459cSmrg}
12426fa459cSmrg
12526fa459cSmrg#undef HashComposite
126