From 525eb2983b818f9de599c0182e518648b1c5c41a Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 22 Feb 2015 15:26:30 +0100 Subject: [PATCH] Slightly faster resource lookup. --- http_examples.cpp | 2 +- https_examples.cpp | 2 +- server_http.hpp | 45 ++++++++++++++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/http_examples.cpp b/http_examples.cpp index 96650ab..f00faeb 100644 --- a/http_examples.cpp +++ b/http_examples.cpp @@ -71,7 +71,7 @@ int main() { //GET-example for the path /match/[number], responds with the matched string in path (number) //For instance a request GET /match/123 will receive: 123 - server.resource["^/match/([0-9]+)/?$"]["GET"]=[](HttpServer::Response& response, shared_ptr request) { + server.resource["^/match/([0-9]+)$"]["GET"]=[](HttpServer::Response& response, shared_ptr request) { string number=request->path_match[1]; response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number; }; diff --git a/https_examples.cpp b/https_examples.cpp index f04118a..f2ac0c6 100644 --- a/https_examples.cpp +++ b/https_examples.cpp @@ -71,7 +71,7 @@ int main() { //GET-example for the path /match/[number], responds with the matched string in path (number) //For instance a request GET /match/123 will receive: 123 - server.resource["^/match/([0-9]+)/?$"]["GET"]=[](HttpsServer::Response& response, shared_ptr request) { + server.resource["^/match/([0-9]+)$"]["GET"]=[](HttpsServer::Response& response, shared_ptr request) { string number=request->path_match[1]; response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number; }; diff --git a/server_http.hpp b/server_http.hpp index f6c7d3a..d82bda3 100644 --- a/server_http.hpp +++ b/server_http.hpp @@ -137,17 +137,31 @@ namespace SimpleWeb { std::function::Response&, std::shared_ptr::Request>)> > default_resource; private: - std::vector::Response&, std::shared_ptr::Request>)> > > > regex_resource; + std::vector::Response&, std::shared_ptr::Request>)> > > > > opt_resource; public: void start() { - //Move the resources with regular expressions to regex_resource for more efficient request processing - for(auto it=resource.begin();it!=resource.end();) { - regex_resource.emplace_back(std::regex(it->first), std::move(it->second)); - it=resource.erase(it); + //Copy the resources to opt_resource for more efficient request processing + opt_resource.clear(); + for(auto& res: resource) { + for(auto& res_method: res.second) { + auto it=opt_resource.end(); + for(auto opt_it=opt_resource.begin();opt_it!=opt_resource.end();opt_it++) { + if(res_method.first==opt_it->first) { + it=opt_it; + break; + } + } + if(it==opt_resource.end()) { + opt_resource.emplace_back(); + it=opt_resource.begin()+(opt_resource.size()-1); + it->first=res_method.first; + } + it->second.emplace_back(std::regex(res.first), res_method.second); + } } - + accept(); //If num_threads>1, start m_io_service.run() in (num_threads-1) threads for thread-pooling @@ -287,14 +301,15 @@ namespace SimpleWeb { void find_resource(std::shared_ptr socket, std::shared_ptr request) { //Find path- and method-match, and call write_response - for(auto& res: regex_resource) { - auto it_method=res.second.find(request->method); - if(it_method!=res.second.end()) { - std::smatch sm_res; - if(std::regex_match(request->path, sm_res, res.first)) { - request->path_match=std::move(sm_res); - write_response(socket, request, it_method->second); - return; + for(auto& res: opt_resource) { + if(request->method==res.first) { + for(auto& res_path: res.second) { + std::smatch sm_res; + if(std::regex_match(request->path, sm_res, res_path.first)) { + request->path_match=std::move(sm_res); + write_response(socket, request, res_path.second); + return; + } } } }