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
357
  create(DataInputPtr<DataType>&& data_input, absl::optional<OnMatch<DataType>> on_no_match) {
16
357
    absl::Status creation_status = absl::OkStatus();
17
357
    auto ret = std::unique_ptr<ExactMapMatcher<DataType>>(
18
357
        new ExactMapMatcher<DataType>(std::move(data_input), on_no_match, creation_status));
19
357
    RETURN_IF_NOT_OK_REF(creation_status);
20
356
    return ret;
21
357
  }
22

            
23
394
  void addChild(std::string value, OnMatch<DataType>&& on_match) override {
24
394
    const auto itr_and_exists = children_.emplace(value, std::move(on_match));
25
394
    ASSERT(itr_and_exists.second);
26
394
  }
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
357
      : 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
295
                            SkippedMatchCb skipped_match_cb) override {
37
295
    const auto itr = children_.find(key);
38
295
    if (itr != children_.end()) {
39
242
      ActionMatchResult result =
40
242
          MatchTree<DataType>::handleRecursionAndSkips(itr->second, data, skipped_match_cb);
41
242
      if (!result.isNoMatch()) {
42
236
        return result;
43
236
      }
44
242
    }
45
59
    return this->doNoMatch(data, skipped_match_cb);
46
295
  }
47

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