Repository: envoyproxy/envoy
File: source/common/router/config_impl.h (C/C++)

Code before:

  using WildcardVirtualHosts =
      std::map<int64_t, absl::node_hash_map<std::string, VirtualHostImplSharedPtr>, std::greater<>>;
  using SubstringFunction = std::function<absl::string_view(absl::string_view, int)>;
  const VirtualHostImpl* findWildcardVirtualHost(absl::string_view host,
                                                 const WildcardVirtualHosts& wildcard_virtual_hosts,
                                                 SubstringFunction substring_function) const;
  bool ignorePortInHostMatching() const { return ignore_port_in_host_matching_; }

  Stats::ScopeSharedPtr vhost_scope_;
  absl::node_hash_map<std::string, VirtualHostImplSharedPtr> virtual_hosts_;
  // std::greater as a minor optimization to iterate from more to less specific
  //
  // A note on using an unordered_map versus a vector of (string, VirtualHostImplSharedPtr) pairs:
  //
  // Based on local benchmarks, each vector entry costs around 20ns for recall and (string)
  // comparison with a fixed cost of about 25ns. For unordered_map, the empty map costs about 65ns
  // and climbs to about 110ns once there are any entries.
  //
  // The break-even is 4 entries.
  WildcardVirtualHosts wildcard_virtual_host_suffixes_;
  WildcardVirtualHosts wildcard_virtual_host_prefixes_;

  VirtualHostImplSharedPtr default_virtual_host_;
  const bool ignore_port_in_host_matching_{false};
  const std::string vhost_header_;
};

/**
 * Shared part of the route configuration implementation.
 */
class CommonConfigImpl : public CommonConfig {
public:
  static absl::StatusOr<std::shared_ptr<CommonConfigImpl>>
  create(const envoy::config::route::v3::RouteConfiguration& config,
         Server::Configuration::ServerFactoryContext& factory_context,
         ProtobufMessage::ValidationVisitor& validator);

  const HeaderParser& requestHeaderParser() const {
    if (request_headers_parser_ != nullptr) {
      return *request_headers_parser_;
    }
    return HeaderParser::defaultParser();
  }
  const HeaderParser& responseHeaderParser() const {
    if (response_headers_parser_ != nullptr) {
      return *response_headers_parser_;
    }
    return HeaderParser::defaultParser();
  }


Review comment (suggestion):
```suggestion
  const Http::LowerCaseString vhost_header_;
```

to avoid create the lower case string copy for every match.

Code after:

  using WildcardVirtualHosts =
      std::map<int64_t, absl::node_hash_map<std::string, VirtualHostImplSharedPtr>, std::greater<>>;
  using SubstringFunction = std::function<absl::string_view(absl::string_view, int)>;
  const VirtualHostImpl* findWildcardVirtualHost(absl::string_view host,
                                                 const WildcardVirtualHosts& wildcard_virtual_hosts,
                                                 SubstringFunction substring_function) const;
  bool ignorePortInHostMatching() const { return ignore_port_in_host_matching_; }

  Stats::ScopeSharedPtr vhost_scope_;
  absl::node_hash_map<std::string, VirtualHostImplSharedPtr> virtual_hosts_;
  // std::greater as a minor optimization to iterate from more to less specific
  //
  // A note on using an unordered_map versus a vector of (string, VirtualHostImplSharedPtr) pairs:
  //
  // Based on local benchmarks, each vector entry costs around 20ns for recall and (string)
  // comparison with a fixed cost of about 25ns. For unordered_map, the empty map costs about 65ns
  // and climbs to about 110ns once there are any entries.
  //
  // The break-even is 4 entries.
  WildcardVirtualHosts wildcard_virtual_host_suffixes_;
  WildcardVirtualHosts wildcard_virtual_host_prefixes_;

  VirtualHostImplSharedPtr default_virtual_host_;
  const bool ignore_port_in_host_matching_{false};
  const Http::LowerCaseString vhost_header_;
};

/**
 * Shared part of the route configuration implementation.
 */
class CommonConfigImpl : public CommonConfig {
public:
  static absl::StatusOr<std::shared_ptr<CommonConfigImpl>>
  create(const envoy::config::route::v3::RouteConfiguration& config,
         Server::Configuration::ServerFactoryContext& factory_context,
         ProtobufMessage::ValidationVisitor& validator);

  const HeaderParser& requestHeaderParser() const {
    if (request_headers_parser_ != nullptr) {
      return *request_headers_parser_;
    }
    return HeaderParser::defaultParser();
  }
  const HeaderParser& responseHeaderParser() const {
    if (response_headers_parser_ != nullptr) {
      return *response_headers_parser_;
    }
    return HeaderParser::defaultParser();
  }