From 5f6cac915547b9598a4237240c29b4a06f7f5d37 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 May 2011 09:16:04 +0000 Subject: [PATCH] make sure any data structure is only loaded once. saves roughly 25% of RAM and starts up 10% faster on benchmark instances. --- Plugins/LocatePlugin.h | 12 ++--- Plugins/NearestPlugin.h | 12 ++--- Plugins/ObjectForPluginStruct.h | 77 ++++++++++++++++++++++++++ Plugins/RoutePlugin.h | 44 +++------------ routed.cpp | 96 ++++++++++++++++----------------- 5 files changed, 140 insertions(+), 101 deletions(-) create mode 100644 Plugins/ObjectForPluginStruct.h diff --git a/Plugins/LocatePlugin.h b/Plugins/LocatePlugin.h index d3974c0db..122bde13d 100644 --- a/Plugins/LocatePlugin.h +++ b/Plugins/LocatePlugin.h @@ -23,6 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include +#include "ObjectForPluginStruct.h" #include "BasePlugin.h" #include "RouteParameters.h" @@ -33,14 +34,9 @@ or see http://www.gnu.org/licenses/agpl.txt. */ class LocatePlugin : public BasePlugin { public: - LocatePlugin(std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath) { - nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str()); - ifstream nodesInStream(nodesPath.c_str(), ios::binary); - nodeHelpDesk->initNNGrid(nodesInStream); - } - ~LocatePlugin() { - delete nodeHelpDesk; - } + LocatePlugin(ObjectsForQueryStruct * objects) { + nodeHelpDesk = objects->nodeHelpDesk; + } std::string GetDescriptor() { return std::string("locate"); } std::string GetVersionString() { return std::string("0.3 (DL)"); } void HandleRequest(RouteParameters routeParameters, http::Reply& reply) { diff --git a/Plugins/NearestPlugin.h b/Plugins/NearestPlugin.h index 29f2e13da..fb1c83e87 100644 --- a/Plugins/NearestPlugin.h +++ b/Plugins/NearestPlugin.h @@ -25,6 +25,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "BasePlugin.h" #include "RouteParameters.h" + +#include "ObjectForPluginStruct.h" + #include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/HashTable.h" #include "../Util/StrIngUtil.h" @@ -34,17 +37,12 @@ or see http://www.gnu.org/licenses/agpl.txt. */ class NearestPlugin : public BasePlugin { public: - NearestPlugin(std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath) { - nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str()); - ifstream nodesInStream(nodesPath.c_str(), ios::binary); - nodeHelpDesk->initNNGrid(nodesInStream); + NearestPlugin(ObjectsForQueryStruct * objects) { + nodeHelpDesk = objects->nodeHelpDesk; descriptorTable.Set("", 0); //default descriptor descriptorTable.Set("kml", 0); descriptorTable.Set("json", 1); } - ~NearestPlugin() { - delete nodeHelpDesk; - } std::string GetDescriptor() { return std::string("nearest"); } std::string GetVersionString() { return std::string("0.3 (DL)"); } void HandleRequest(RouteParameters routeParameters, http::Reply& reply) { diff --git a/Plugins/ObjectForPluginStruct.h b/Plugins/ObjectForPluginStruct.h new file mode 100644 index 000000000..2571c97f9 --- /dev/null +++ b/Plugins/ObjectForPluginStruct.h @@ -0,0 +1,77 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. + */ + + +#ifndef OBJECTFORPLUGINSTRUCT_H_ +#define OBJECTFORPLUGINSTRUCT_H_ + +#include "../DataStructures/StaticGraph.h" +#include "../Util/GraphLoader.h" + +typedef ContractionCleanup::Edge::EdgeData EdgeData; +typedef StaticGraph::InputEdge InputEdge; + +struct ObjectsForQueryStruct { + ObjectsForQueryStruct(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string namesPath, std::string psd = "route") { + std::cout << "[objects] loading query data structures ..." << std::flush; + //Init nearest neighbor data structure + ifstream nodesInStream(nodesPath.c_str(), ios::binary); + nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str()); + nodeHelpDesk->initNNGrid(nodesInStream); + + ifstream hsgrInStream(hsgrPath.c_str(), ios::binary); + //Deserialize road network graph + std::vector< InputEdge> * edgeList = new std::vector< InputEdge>(); + readHSGRFromStream(hsgrInStream, edgeList); + graph = new StaticGraph(nodeHelpDesk->getNumberOfNodes()-1, *edgeList); + delete edgeList; + + //deserialize street name list + ifstream namesInStream(namesPath.c_str(), ios::binary); + unsigned size = 0; + namesInStream.read((char *)&size, sizeof(unsigned)); + names = new std::vector(); + + char buf[1024]; + for(unsigned i = 0; i < size; i++) { + unsigned sizeOfString = 0; + namesInStream.read((char *)&sizeOfString, sizeof(unsigned)); + memset(buf, 0, 1024*sizeof(char)); + namesInStream.read(buf, sizeOfString); + std::string currentStreetName(buf); + names->push_back(currentStreetName); + } + hsgrInStream.close(); + namesInStream.close(); + std::cout << "ok" << std::endl; + } + + ~ObjectsForQueryStruct() { + delete names; + delete graph; + delete nodeHelpDesk; + } + + NodeInformationHelpDesk * nodeHelpDesk; + std::vector * names; + StaticGraph * graph; +}; + +#endif /* OBJECTFORPLUGINSTRUCT_H_ */ diff --git a/Plugins/RoutePlugin.h b/Plugins/RoutePlugin.h index 1ed0cfe02..0bd0ec68b 100644 --- a/Plugins/RoutePlugin.h +++ b/Plugins/RoutePlugin.h @@ -27,6 +27,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include +#include "ObjectForPluginStruct.h" + #include "BaseDescriptor.h" #include "BasePlugin.h" #include "RouteParameters.h" @@ -37,56 +39,24 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "../DataStructures/StaticGraph.h" #include "../DataStructures/SearchEngine.h" -#include "../Util/GraphLoader.h" #include "../Util/StrIngUtil.h" -typedef ContractionCleanup::Edge::EdgeData EdgeData; -typedef StaticGraph::InputEdge InputEdge; - class RoutePlugin : public BasePlugin { public: - RoutePlugin(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string namesPath, std::string psd = "route") { - //Init nearest neighbor data structure - nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str()); - ifstream nodesInStream(nodesPath.c_str(), ios::binary); - ifstream hsgrInStream(hsgrPath.c_str(), ios::binary); - nodeHelpDesk->initNNGrid(nodesInStream); - //Deserialize road network graph - std::vector< InputEdge> * edgeList = new std::vector< InputEdge>(); - readHSGRFromStream(hsgrInStream, edgeList); - hsgrInStream.close(); - graph = new StaticGraph(nodeHelpDesk->getNumberOfNodes()-1, *edgeList); - delete edgeList; + RoutePlugin(ObjectsForQueryStruct * objects, std::string psd = "route") : pluginDescriptorString(psd) { + nodeHelpDesk = objects->nodeHelpDesk; + graph = objects->graph; + names = objects->names; - //deserialize street name list - ifstream namesInStream(namesPath.c_str(), ios::binary); - unsigned size = 0; - namesInStream.read((char *)&size, sizeof(unsigned)); - names = new std::vector(); - - char buf[1024]; - for(unsigned i = 0; i < size; i++) { - unsigned sizeOfString = 0; - namesInStream.read((char *)&sizeOfString, sizeof(unsigned)); - memset(buf, 0, 1024*sizeof(char)); - namesInStream.read(buf, sizeOfString); - std::string currentStreetName(buf); - names->push_back(currentStreetName); - } - - //init complete search engine sEngine = new SearchEngine >(graph, nodeHelpDesk, names); descriptorTable.Set("", 0); //default descriptor descriptorTable.Set("kml", 0); descriptorTable.Set("json", 1); - pluginDescriptorString = psd; } + ~RoutePlugin() { - delete names; delete sEngine; - delete graph; - delete nodeHelpDesk; } std::string GetDescriptor() { return pluginDescriptorString; } diff --git a/routed.cpp b/routed.cpp index b365d52c2..d3a92083e 100644 --- a/routed.cpp +++ b/routed.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. -*/ + */ #include @@ -30,6 +30,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Server/ServerConfiguration.h" #include "Server/ServerFactory.h" +#include "Plugins/ObjectForPluginStruct.h" + #include "Plugins/HelloWorldPlugin.h" #include "Plugins/LocatePlugin.h" #include "Plugins/NearestPlugin.h" @@ -42,63 +44,59 @@ typedef http::RequestHandler RequestHandler; int main (int argc, char *argv[]) { - if(testDataFiles(argc, argv)==false) { - std::cerr << "[error] at least one data file name seems to be bogus!" << std::endl; - exit(-1); - } + if(testDataFiles(argc, argv)==false) { + std::cerr << "[error] at least one data file name seems to be bogus!" << std::endl; + exit(-1); + } - try { - std::cout << "[server] starting up engines, compiled at " << __TIMESTAMP__ << std::endl; - int sig = 0; - sigset_t new_mask; - sigset_t old_mask; - sigfillset(&new_mask); - pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); + try { + std::cout << "[server] starting up engines, compiled at " << __TIMESTAMP__ << std::endl; + int sig = 0; + sigset_t new_mask; + sigset_t old_mask; + sigfillset(&new_mask); + pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); - ServerConfiguration serverConfig("server.ini"); - Server * s = ServerFactory::CreateServer(serverConfig); - RequestHandler & h = s->GetRequestHandlerPtr(); + ServerConfiguration serverConfig("server.ini"); + Server * s = ServerFactory::CreateServer(serverConfig); + RequestHandler & h = s->GetRequestHandlerPtr(); - BasePlugin * helloWorld = new HelloWorldPlugin(); - h.RegisterPlugin(helloWorld); - - BasePlugin * locate = new LocatePlugin( + ObjectsForQueryStruct * objects = new ObjectsForQueryStruct(serverConfig.GetParameter("hsgrData"), serverConfig.GetParameter("ramIndex"), serverConfig.GetParameter("fileIndex"), - serverConfig.GetParameter("nodesData")); + serverConfig.GetParameter("nodesData"), + serverConfig.GetParameter("namesData")); + + BasePlugin * helloWorld = new HelloWorldPlugin(); + h.RegisterPlugin(helloWorld); + + BasePlugin * locate = new LocatePlugin(objects); h.RegisterPlugin(locate); - BasePlugin * nearest = new NearestPlugin( - serverConfig.GetParameter("ramIndex"), - serverConfig.GetParameter("fileIndex"), - serverConfig.GetParameter("nodesData")); + BasePlugin * nearest = new NearestPlugin(objects); h.RegisterPlugin(nearest); - BasePlugin * route = new RoutePlugin( - serverConfig.GetParameter("hsgrData"), - serverConfig.GetParameter("ramIndex"), - serverConfig.GetParameter("fileIndex"), - serverConfig.GetParameter("nodesData"), - serverConfig.GetParameter("namesData")); - h.RegisterPlugin(route); + BasePlugin * route = new RoutePlugin(objects); + h.RegisterPlugin(route); - boost::thread t(boost::bind(&Server::Run, s)); + boost::thread t(boost::bind(&Server::Run, s)); - sigset_t wait_mask; - pthread_sigmask(SIG_SETMASK, &old_mask, 0); - sigemptyset(&wait_mask); - sigaddset(&wait_mask, SIGINT); - sigaddset(&wait_mask, SIGQUIT); - sigaddset(&wait_mask, SIGTERM); - pthread_sigmask(SIG_BLOCK, &wait_mask, 0); - std::cout << "[server] running and waiting for requests" << std::endl; - sigwait(&wait_mask, &sig); - std::cout << std::endl << "[server] shutting down" << std::endl; - s->Stop(); - t.join(); - delete s; - } catch (std::exception& e) { - std::cerr << "[fatal error] exception: " << e.what() << std::endl; - } - return 0; + sigset_t wait_mask; + pthread_sigmask(SIG_SETMASK, &old_mask, 0); + sigemptyset(&wait_mask); + sigaddset(&wait_mask, SIGINT); + sigaddset(&wait_mask, SIGQUIT); + sigaddset(&wait_mask, SIGTERM); + pthread_sigmask(SIG_BLOCK, &wait_mask, 0); + std::cout << "[server] running and waiting for requests" << std::endl; + sigwait(&wait_mask, &sig); + std::cout << std::endl << "[server] shutting down" << std::endl; + s->Stop(); + t.join(); + delete s; + delete objects; + } catch (std::exception& e) { + std::cerr << "[fatal error] exception: " << e.what() << std::endl; + } + return 0; }