summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-05-15 19:36:52 +0200
committerRoland Reichwein <mail@reichwein.it>2020-05-15 19:36:52 +0200
commit8fbada6c7542d233afb4677c19a0395f77d32519 (patch)
tree574e5576352510cc52df82d9629d6e3dfc767518
parent48908fb0bba69404dfd86d1af3b9ace1e0d598c9 (diff)
Speed up GetPath() with look up table
-rw-r--r--config.cpp53
-rw-r--r--config.h4
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<std::string> serve_sites; // if empty, automatically expand to all configured sites
+
+ std::unordered_map <std::string, Site*> 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;