Move option parsing to own class

This commit is contained in:
Patrick Niklaus 2015-04-24 14:51:25 +02:00
parent 1f985d04a2
commit a46bcf45d5
8 changed files with 295 additions and 198 deletions

View File

@ -0,0 +1,136 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "contractor_options.hpp"
#include "../util/git_sha.hpp"
#include "../util/ini_file.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
return_code
ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &contractor_config)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c", boost::program_options::value<boost::filesystem::path>(&contractor_config.config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&contractor_config.restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p", boost::program_options::value<boost::filesystem::path>(&contractor_config.profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t", boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i", boost::program_options::value<boost::filesystem::path>(&contractor_config.osrm_input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(
temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return return_code::fail;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::fail;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
contractor_config.restrictions_path = contractor_config.osrm_input_path.string() + ".restrictions";
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::fail;
}
return return_code::ok;
}
void ContractorOptions::GenerateOutputFilesNames(ContractorConfig &contractor_config)
{
contractor_config.node_output_path = contractor_config.osrm_input_path.string() + ".nodes";
contractor_config.edge_output_path = contractor_config.osrm_input_path.string() + ".edges";
contractor_config.geometry_output_path = contractor_config.osrm_input_path.string() + ".geometry";
contractor_config.graph_output_path = contractor_config.osrm_input_path.string() + ".hsgr";
contractor_config.rtree_nodes_output_path = contractor_config.osrm_input_path.string() + ".ramIndex";
contractor_config.rtree_leafs_output_path = contractor_config.osrm_input_path.string() + ".fileIndex";
}

View File

@ -0,0 +1,68 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONTRACTOR_OPTIONS_HPP
#define CONTRACTOR_OPTIONS_HPP
#include <boost/filesystem/path.hpp>
#include <string>
enum class return_code : unsigned
{
ok,
fail,
exit
};
struct ContractorConfig
{
ContractorConfig() noexcept : requested_num_threads(0) {}
boost::filesystem::path config_file_path;
boost::filesystem::path osrm_input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path profile_path;
std::string node_output_path;
std::string edge_output_path;
std::string geometry_output_path;
std::string graph_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
unsigned requested_num_threads;
};
struct ContractorOptions
{
static return_code ParseArguments(int argc, char *argv[], ContractorConfig &extractor_config);
static void GenerateOutputFilesNames(ContractorConfig &extractor_config);
};
#endif // EXTRACTOR_OPTIONS_HPP

View File

@ -48,7 +48,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <tbb/parallel_sort.h> #include <tbb/parallel_sort.h>
#include <chrono> #include <chrono>
@ -57,11 +56,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <thread> #include <thread>
#include <vector> #include <vector>
Prepare::Prepare() : requested_num_threads(1) {}
Prepare::~Prepare() {} Prepare::~Prepare() {}
int Prepare::Process(int argc, char *argv[]) int Prepare::Run()
{ {
#ifdef WIN32 #ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing") #pragma message("Memory consumption on Windows can be higher due to different bit packing")
@ -72,55 +69,8 @@ int Prepare::Process(int argc, char *argv[])
"changing EdgeBasedEdge type has influence on memory consumption!"); "changing EdgeBasedEdge type has influence on memory consumption!");
#endif #endif
LogPolicy::GetInstance().Unmute();
TIMER_START(preparing); TIMER_START(preparing);
if (!ParseArguments(argc, argv))
{
return 0;
}
if (!boost::filesystem::is_regular_file(osrm_input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << osrm_input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
return 1;
}
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << osrm_input_path.filename().string();
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
LogPolicy::GetInstance().Unmute();
node_output_path = osrm_input_path.string() + ".nodes";
edge_output_path = osrm_input_path.string() + ".edges";
geometry_output_path = osrm_input_path.string() + ".geometry";
graph_output_path = osrm_input_path.string() + ".hsgr";
rtree_nodes_output_path = osrm_input_path.string() + ".ramIndex";
rtree_leafs_output_path = osrm_input_path.string() + ".fileIndex";
// Create a new lua state // Create a new lua state
SimpleLogger().Write() << "Generating edge-expanded graph representation"; SimpleLogger().Write() << "Generating edge-expanded graph representation";
@ -192,7 +142,7 @@ std::size_t Prepare::WriteContractedGraph(unsigned number_of_edge_based_nodes,
<< " edges"; << " edges";
FingerPrint fingerprint_orig; FingerPrint fingerprint_orig;
boost::filesystem::ofstream hsgr_output_stream(graph_output_path, std::ios::binary); boost::filesystem::ofstream hsgr_output_stream(config.graph_output_path, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint)); hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint));
const unsigned max_used_node_id = 1 + [&contracted_edge_list] const unsigned max_used_node_id = 1 + [&contracted_edge_list]
{ {
@ -308,101 +258,6 @@ unsigned Prepare::CalculateEdgeChecksum(std::unique_ptr<std::vector<EdgeBasedNod
return crc32_value; return crc32_value;
} }
/**
\brief Parses command line arguments
\param argc count of arguments
\param argv array of arguments
\param result [out] value for exit return value
\return true if everything is ok, false if need to terminate execution
*/
bool Prepare::ParseArguments(int argc, char *argv[])
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t", boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i", boost::program_options::value<boost::filesystem::path>(&osrm_input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(
temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
restrictions_path = std::string(osrm_input_path.string() + ".restrictions");
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
return true;
}
/** /**
\brief Setups scripting environment (lua-scripting) \brief Setups scripting environment (lua-scripting)
Also initializes speed profile. Also initializes speed profile.
@ -414,10 +269,10 @@ void Prepare::SetupScriptingEnvironment(
luaL_openlibs(lua_state); luaL_openlibs(lua_state);
// adjust lua load path // adjust lua load path
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str()); luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
// Now call our function in a lua script // Now call our function in a lua script
if (0 != luaL_dofile(lua_state, profile_path.string().c_str())) if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
{ {
std::stringstream msg; std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occured in scripting block"; msg << lua_tostring(lua_state, -1) << " occured in scripting block";
@ -451,7 +306,7 @@ void Prepare::SetupScriptingEnvironment(
void Prepare::LoadRestrictionMap(const std::unordered_map<NodeID, NodeID> &external_to_internal_node_map, void Prepare::LoadRestrictionMap(const std::unordered_map<NodeID, NodeID> &external_to_internal_node_map,
RestrictionMap &restriction_map) RestrictionMap &restriction_map)
{ {
boost::filesystem::ifstream input_stream(restrictions_path, std::ios::in | std::ios::binary); boost::filesystem::ifstream input_stream(config.restrictions_path, std::ios::in | std::ios::binary);
std::vector<TurnRestriction> restriction_list; std::vector<TurnRestriction> restriction_list;
loadRestrictionsFromFile(input_stream, external_to_internal_node_map, restriction_list); loadRestrictionsFromFile(input_stream, external_to_internal_node_map, restriction_list);
@ -473,7 +328,7 @@ Prepare::LoadNodeBasedGraph(std::vector<NodeID> &barrier_node_list,
std::vector<ImportEdge> edge_list; std::vector<ImportEdge> edge_list;
std::unordered_map<NodeID, NodeID> external_to_internal_node_map; std::unordered_map<NodeID, NodeID> external_to_internal_node_map;
boost::filesystem::ifstream input_stream(osrm_input_path, std::ios::in | std::ios::binary); boost::filesystem::ifstream input_stream(config.osrm_input_path, std::ios::in | std::ios::binary);
NodeID number_of_node_based_nodes = loadNodesFromFile(input_stream, NodeID number_of_node_based_nodes = loadNodesFromFile(input_stream,
barrier_node_list, traffic_light_list, barrier_node_list, traffic_light_list,
@ -527,7 +382,7 @@ Prepare::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_nod
internal_to_external_node_map, internal_to_external_node_map,
speed_profile); speed_profile);
edge_based_graph_factory.Run(edge_output_path, geometry_output_path, lua_state); edge_based_graph_factory.Run(config.edge_output_path, config.geometry_output_path, lua_state);
lua_close(lua_state); lua_close(lua_state);
const std::size_t number_of_edge_based_nodes = const std::size_t number_of_edge_based_nodes =
@ -558,7 +413,7 @@ void Prepare::ContractGraph(const std::size_t number_of_edge_based_nodes,
*/ */
void Prepare::WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map) void Prepare::WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map)
{ {
boost::filesystem::ofstream node_stream(node_output_path, std::ios::binary); boost::filesystem::ofstream node_stream(config.node_output_path, std::ios::binary);
const unsigned size_of_mapping = internal_to_external_node_map->size(); const unsigned size_of_mapping = internal_to_external_node_map->size();
node_stream.write((char *)&size_of_mapping, sizeof(unsigned)); node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
if (size_of_mapping > 0) if (size_of_mapping > 0)
@ -576,6 +431,6 @@ void Prepare::WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_
*/ */
void Prepare::BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list, const std::vector<QueryNode>& internal_to_external_node_map) void Prepare::BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list, const std::vector<QueryNode>& internal_to_external_node_map)
{ {
StaticRTree<EdgeBasedNode>(node_based_edge_list, rtree_nodes_output_path.c_str(), StaticRTree<EdgeBasedNode>(node_based_edge_list, config.rtree_nodes_output_path.c_str(),
rtree_leafs_output_path.c_str(), internal_to_external_node_map); config.rtree_leafs_output_path.c_str(), internal_to_external_node_map);
} }

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROCESSING_CHAIN_HPP #ifndef PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_HPP #define PROCESSING_CHAIN_HPP
#include "contractor_options.hpp"
#include "edge_based_graph_factory.hpp" #include "edge_based_graph_factory.hpp"
#include "../data_structures/query_edge.hpp" #include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp" #include "../data_structures/static_graph.hpp"
@ -50,14 +51,14 @@ class Prepare
using InputEdge = DynamicGraph<EdgeData>::InputEdge; using InputEdge = DynamicGraph<EdgeData>::InputEdge;
using StaticEdge = StaticGraph<EdgeData>::InputEdge; using StaticEdge = StaticGraph<EdgeData>::InputEdge;
explicit Prepare(); explicit Prepare(const ContractorConfig& contractor_config)
: config(contractor_config) {}
Prepare(const Prepare &) = delete; Prepare(const Prepare &) = delete;
~Prepare(); ~Prepare();
int Process(int argc, char *argv[]); int Run();
protected: protected:
bool ParseArguments(int argc, char *argv[]);
void SetupScriptingEnvironment(lua_State *myLuaState, void SetupScriptingEnvironment(lua_State *myLuaState,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile); EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
void LoadRestrictionMap(const std::unordered_map<NodeID, NodeID> &external_to_internal_node_map, void LoadRestrictionMap(const std::unordered_map<NodeID, NodeID> &external_to_internal_node_map,
@ -80,22 +81,8 @@ class Prepare
void WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map); void WriteNodeMapping(std::unique_ptr<std::vector<QueryNode>> internal_to_external_node_map);
void BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list, void BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list,
const std::vector<QueryNode> &internal_to_external_node_map); const std::vector<QueryNode> &internal_to_external_node_map);
private: private:
ContractorConfig config;
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path osrm_input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path preinfo_path;
boost::filesystem::path profile_path;
std::string node_output_path;
std::string edge_output_path;
std::string geometry_output_path;
std::string graph_output_path;
std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path;
}; };
#endif // PROCESSING_CHAIN_HPP #endif // PROCESSING_CHAIN_HPP

View File

@ -73,7 +73,7 @@ int main(int argc, char *argv[])
<< " not found!"; << " not found!";
return 1; return 1;
} }
return extractor().run(extractor_config); return extractor(extractor_config).run();
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {

View File

@ -82,7 +82,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* .restrictions : Turn restrictions that are used my osrm-prepare to construct the edge-expanded graph * .restrictions : Turn restrictions that are used my osrm-prepare to construct the edge-expanded graph
* *
*/ */
int extractor::run(const ExtractorConfig &extractor_config) int extractor::run()
{ {
try try
{ {
@ -91,20 +91,20 @@ int extractor::run(const ExtractorConfig &extractor_config)
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads(); const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
const auto number_of_threads = const auto number_of_threads =
std::min(recommended_num_threads, extractor_config.requested_num_threads); std::min(recommended_num_threads, config.requested_num_threads);
tbb::task_scheduler_init init(number_of_threads); tbb::task_scheduler_init init(number_of_threads);
SimpleLogger().Write() << "Input file: " << extractor_config.input_path.filename().string(); SimpleLogger().Write() << "Input file: " << config.input_path.filename().string();
SimpleLogger().Write() << "Profile: " << extractor_config.profile_path.filename().string(); SimpleLogger().Write() << "Profile: " << config.profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << number_of_threads; SimpleLogger().Write() << "Threads: " << number_of_threads;
// setup scripting environment // setup scripting environment
ScriptingEnvironment scripting_environment(extractor_config.profile_path.string().c_str()); ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
ExtractionContainers extraction_containers; ExtractionContainers extraction_containers;
auto extractor_callbacks = osrm::make_unique<ExtractorCallbacks>(extraction_containers); auto extractor_callbacks = osrm::make_unique<ExtractorCallbacks>(extraction_containers);
const osmium::io::File input_file(extractor_config.input_path.string()); const osmium::io::File input_file(config.input_path.string());
osmium::io::Reader reader(input_file); osmium::io::Reader reader(input_file);
const osmium::io::Header header = reader.header(); const osmium::io::Header header = reader.header();
@ -131,7 +131,7 @@ int extractor::run(const ExtractorConfig &extractor_config)
} }
SimpleLogger().Write() << "timestamp: " << timestamp; SimpleLogger().Write() << "timestamp: " << timestamp;
boost::filesystem::ofstream timestamp_out(extractor_config.timestamp_file_name); boost::filesystem::ofstream timestamp_out(config.timestamp_file_name);
timestamp_out.write(timestamp.c_str(), timestamp.length()); timestamp_out.write(timestamp.c_str(), timestamp.length());
timestamp_out.close(); timestamp_out.close();
@ -236,12 +236,12 @@ int extractor::run(const ExtractorConfig &extractor_config)
return 1; return 1;
} }
extraction_containers.PrepareData(extractor_config.output_file_name, extraction_containers.PrepareData(config.output_file_name,
extractor_config.restriction_file_name); config.restriction_file_name);
TIMER_STOP(extracting); TIMER_STOP(extracting);
SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s"; SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s";
SimpleLogger().Write() << "To prepare the data for routing, run: " SimpleLogger().Write() << "To prepare the data for routing, run: "
<< "./osrm-prepare " << extractor_config.output_file_name << "./osrm-prepare " << config.output_file_name
<< std::endl; << std::endl;
} }
catch (std::exception &e) catch (std::exception &e)

View File

@ -30,8 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "extractor_options.hpp" #include "extractor_options.hpp"
struct extractor class extractor
{ {
int run(const ExtractorConfig &extractor_config); public:
extractor(const ExtractorConfig &extractor_config)
: config(extractor_config) {}
int run();
private:
ExtractorConfig config;
}; };
#endif /* EXTRACTOR_HPP */ #endif /* EXTRACTOR_HPP */

View File

@ -26,10 +26,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "contractor/processing_chain.hpp" #include "contractor/processing_chain.hpp"
#include "contractor/contractor_options.hpp"
#include "util/simple_logger.hpp" #include "util/simple_logger.hpp"
#include <boost/program_options/errors.hpp> #include <boost/program_options/errors.hpp>
#include <tbb/task_scheduler_init.h>
#include <exception> #include <exception>
#include <ostream> #include <ostream>
@ -37,21 +40,64 @@ int main(int argc, char *argv[])
{ {
try try
{ {
return Prepare().Process(argc, argv); LogPolicy::GetInstance().Unmute();
} ContractorConfig contractor_config;
catch (boost::program_options::too_many_positional_options_error &)
{ const return_code result = ContractorOptions::ParseArguments(argc, argv, contractor_config);
SimpleLogger().Write(logWARNING) << "Only one file can be specified";
return 1; if (return_code::fail == result)
} {
catch (boost::program_options::error &e) return 1;
{ }
SimpleLogger().Write(logWARNING) << e.what();
return 1; if (return_code::exit == result)
{
return 0;
}
ContractorOptions::GenerateOutputFilesNames(contractor_config);
if (1 > contractor_config.requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
if (recommended_num_threads != contractor_config.requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
if (!boost::filesystem::is_regular_file(contractor_config.osrm_input_path))
{
SimpleLogger().Write(logWARNING)
<< "Input file " << contractor_config.osrm_input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(contractor_config.profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << contractor_config.profile_path.string()
<< " not found!";
return 1;
}
SimpleLogger().Write() << "Input file: " << contractor_config.osrm_input_path.filename().string();
SimpleLogger().Write() << "Restrictions file: " << contractor_config.restrictions_path.filename().string();
SimpleLogger().Write() << "Profile: " << contractor_config.profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << contractor_config.requested_num_threads;
tbb::task_scheduler_init init(contractor_config.requested_num_threads);
return Prepare(contractor_config).Run();
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what() << std::endl; SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return 1; return 1;
} }
} }