From 8fbada6c7542d233afb4677c19a0395f77d32519 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 15 May 2020 19:36:52 +0200 Subject: Speed up GetPath() with look up table --- config.cpp | 53 +++++++++++++++++++++++++++++++++-------------------- config.h | 4 ++++ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/config.cpp b/config.cpp index ed28ea9..b892317 100644 --- a/config.cpp +++ b/config.cpp @@ -160,7 +160,15 @@ void Config::readConfigfile(std::string filename) } } - // expand socket sites + expand_socket_sites(); + + validate(); + + create_look_up_table(); +} + +void Config::expand_socket_sites() +{ for (auto& socket: m_sockets) { if (socket.serve_sites.empty()) { for (const auto& site: m_sites) { @@ -168,8 +176,6 @@ void Config::readConfigfile(std::string filename) } } } - - validate(); } // just throws on inconsistency @@ -183,7 +189,18 @@ void Config::validate() throw std::runtime_error("Found serve_site "s + serve_site + " without configured site"s); } } - +} + +void Config::create_look_up_table() +{ + for (auto& socket: m_sockets) { + for (const auto& site_name: socket.serve_sites) { + Site& site {m_sites.at(site_name)}; // omit error check: validation previously made sure this exists + for (const auto& host: site.hosts) { + socket.host_lut[host] = &site; + } + } + } } Config::Config(const std::string& filename) @@ -276,22 +293,18 @@ const Path& Config::GetPath(const Socket& socket, const std::string& requested_h RemovePortFromHostname(host); - for (const auto& site_name: socket.serve_sites) { - const Site& site {m_sites.at(site_name)}; // omit error check: validation previously made sure this exists - - if (site.hosts.find(host) != site.hosts.end()) { - for (const auto& path: site.paths) { - if (boost::starts_with(requested_path, path.requested) && - ("/?"s.find(requested_path[path.requested.size()]) != std::string::npos || - requested_path[path.requested.size()] == 0 || - requested_path[path.requested.size() - 1] == '/' - ) && - path.requested.size() > path_len) - { - path_len = path.requested.size(); - result = &path; - } - } + const Site& site{*socket.host_lut.at(host)}; // can throw out_of_range + + for (const auto& path: site.paths) { + if (boost::starts_with(requested_path, path.requested) && + ("/?"s.find(requested_path[path.requested.size()]) != std::string::npos || + requested_path[path.requested.size()] == 0 || + requested_path[path.requested.size() - 1] == '/' + ) && + path.requested.size() > path_len) + { + path_len = path.requested.size(); + result = &path; } } diff --git a/config.h b/config.h index e60bba5..a021c80 100644 --- a/config.h +++ b/config.h @@ -37,6 +37,8 @@ struct Socket std::string port; SocketProtocol protocol; std::unordered_set serve_sites; // if empty, automatically expand to all configured sites + + std::unordered_map host_lut; // look up table for fast server decision in GetPath() }; class Config @@ -44,7 +46,9 @@ class Config const std::string default_filename{"/etc/webserver.conf"}; void readConfigfile(std::string filename); + void expand_socket_sites(); void validate(); + void create_look_up_table(); std::string m_user; std::string m_group; -- cgit v1.2.3