1
#include "source/common/router/metadatamatchcriteria_impl.h"
2

            
3
namespace Envoy {
4
namespace Router {
5
std::vector<MetadataMatchCriterionConstSharedPtr>
6
MetadataMatchCriteriaImpl::extractMetadataMatchCriteria(const MetadataMatchCriteriaImpl* parent,
7
158
                                                        const Protobuf::Struct& matches) {
8
158
  std::vector<MetadataMatchCriterionConstSharedPtr> v;
9

            
10
  // Track locations of each name (from the parent) in v to make it
11
  // easier to replace them when the same name exists in matches.
12
158
  absl::node_hash_map<std::string, std::size_t> existing;
13

            
14
158
  if (parent) {
15
55
    for (const auto& it : parent->metadata_match_criteria_) {
16
      // v.size() is the index of the emplaced name.
17
55
      existing.emplace(it->name(), v.size());
18
55
      v.emplace_back(it);
19
55
    }
20
27
  }
21

            
22
  // Add values from matches, replacing name/values copied from parent.
23
244
  for (const auto& it : matches.fields()) {
24
242
    const auto index_it = existing.find(it.first);
25
242
    if (index_it != existing.end()) {
26
19
      v[index_it->second] = std::make_shared<MetadataMatchCriterionImpl>(it.first, it.second);
27
223
    } else {
28
223
      v.emplace_back(std::make_shared<MetadataMatchCriterionImpl>(it.first, it.second));
29
223
    }
30
242
  }
31

            
32
  // Sort criteria by name to speed matching in the subset load balancer.
33
  // See source/docs/subset_load_balancer.md.
34
158
  std::sort(
35
158
      v.begin(), v.end(),
36
158
      [](const MetadataMatchCriterionConstSharedPtr& a,
37
224
         const MetadataMatchCriterionConstSharedPtr& b) -> bool { return a->name() < b->name(); });
38

            
39
158
  return v;
40
158
}
41

            
42
MetadataMatchCriteriaConstPtr
43
4
MetadataMatchCriteriaImpl::filterMatchCriteria(const std::set<std::string>& names) const {
44

            
45
4
  std::vector<MetadataMatchCriterionConstSharedPtr> v;
46

            
47
  // iterating over metadata_match_criteria_ ensures correct order without sorting
48
10
  for (const auto& it : metadata_match_criteria_) {
49
9
    if (names.count(it->name()) == 1) {
50
3
      v.emplace_back(it);
51
3
    }
52
9
  }
53
4
  return MetadataMatchCriteriaImplConstPtr(new MetadataMatchCriteriaImpl(v));
54
4
};
55

            
56
} // namespace Router
57
} // namespace Envoy