1
#pragma once
2

            
3
#include "source/common/matcher/map_matcher.h"
4

            
5
namespace Envoy {
6
namespace Matcher {
7

            
8
/**
9
 * Implementation of a `sublinear` match tree that provides O(1) lookup of exact values,
10
 * with one OnMatch per result.
11
 */
12
template <class DataType> class ExactMapMatcher : public MapMatcher<DataType> {
13
public:
14
  static absl::StatusOr<std::unique_ptr<ExactMapMatcher>>
15
307
  create(DataInputPtr<DataType>&& data_input, absl::optional<OnMatch<DataType>> on_no_match) {
16
307
    absl::Status creation_status = absl::OkStatus();
17
307
    auto ret = std::unique_ptr<ExactMapMatcher<DataType>>(
18
307
        new ExactMapMatcher<DataType>(std::move(data_input), on_no_match, creation_status));
19
307
    RETURN_IF_NOT_OK_REF(creation_status);
20
306
    return ret;
21
307
  }
22

            
23
342
  void addChild(std::string value, OnMatch<DataType>&& on_match) override {
24
342
    const auto itr_and_exists = children_.emplace(value, std::move(on_match));
25
342
    ASSERT(itr_and_exists.second);
26
342
  }
27

            
28
protected:
29
  template <class DataType2, class ActionFactoryContext> friend class MatchTreeFactory;
30

            
31
  ExactMapMatcher(DataInputPtr<DataType>&& data_input,
32
                  absl::optional<OnMatch<DataType>> on_no_match, absl::Status& creation_status)
33
307
      : MapMatcher<DataType>(std::move(data_input), std::move(on_no_match), creation_status) {}
34

            
35
  ActionMatchResult doMatch(const DataType& data, absl::string_view key,
36
249
                            SkippedMatchCb skipped_match_cb) override {
37
249
    const auto itr = children_.find(key);
38
249
    if (itr != children_.end()) {
39
196
      ActionMatchResult result =
40
196
          MatchTree<DataType>::handleRecursionAndSkips(itr->second, data, skipped_match_cb);
41
196
      if (!result.isNoMatch()) {
42
190
        return result;
43
190
      }
44
196
    }
45
59
    return this->doNoMatch(data, skipped_match_cb);
46
249
  }
47

            
48
private:
49
  absl::flat_hash_map<std::string, OnMatch<DataType>> children_;
50
};
51
} // namespace Matcher
52
} // namespace Envoy