1
#pragma once
2

            
3
#include "envoy/matcher/matcher.h"
4

            
5
#include "source/common/common/hash.h"
6

            
7
namespace Envoy {
8
namespace Extensions {
9
namespace Matching {
10
namespace InputMatchers {
11
namespace ConsistentHashing {
12

            
13
class Matcher : public Envoy::Matcher::InputMatcher {
14
public:
15
  Matcher(uint32_t threshold, uint32_t modulo, uint64_t seed)
16
13
      : threshold_(threshold), modulo_(modulo), seed_(seed) {}
17
12
  ::Envoy::Matcher::MatchResult match(const Envoy::Matcher::DataInputGetResult& input) override {
18
12
    auto data = input.stringData();
19
    // Only match if the value is present.
20
12
    if (!data) {
21
2
      return ::Envoy::Matcher::MatchResult::NoMatch;
22
2
    }
23

            
24
    // Otherwise, match if (hash(input) % modulo) >= threshold.
25
10
    if (HashUtil::xxHash64(*data, seed_) % modulo_ >= threshold_) {
26
7
      return ::Envoy::Matcher::MatchResult::Matched;
27
7
    }
28
3
    return ::Envoy::Matcher::MatchResult::NoMatch;
29
10
  }
30

            
31
private:
32
  const uint32_t threshold_;
33
  const uint32_t modulo_;
34
  const uint64_t seed_;
35
};
36
} // namespace ConsistentHashing
37
} // namespace InputMatchers
38
} // namespace Matching
39
} // namespace Extensions
40
} // namespace Envoy