Create public facing libraries for extractor, contractor and datastore

New libraries libosrm_extract, libosrm_contract, libosrm_store
This commit is contained in:
Patrick Niklaus
2016-01-07 19:19:55 +01:00
parent b36145e3c4
commit 439eb9da3d
68 changed files with 3266 additions and 3104 deletions
+60 -60
View File
@@ -11,6 +11,7 @@
#include <memory>
#include <vector>
#include <cstdlib>
namespace osrm
{
@@ -22,72 +23,71 @@ using QueryGraph = util::StaticGraph<EdgeData>;
}
}
int main(int argc, char *argv[])
int main(int argc, char *argv[]) try
{
osrm::util::LogPolicy::GetInstance().Unmute();
try
if (argc != 2)
{
if (argc != 2)
osrm::util::SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " <file.hsgr>";
return EXIT_FAILURE;
}
boost::filesystem::path hsgr_path(argv[1]);
std::vector<osrm::tools::QueryGraph::NodeArrayEntry> node_list;
std::vector<osrm::tools::QueryGraph::EdgeArrayEntry> edge_list;
osrm::util::SimpleLogger().Write() << "loading graph from " << hsgr_path.string();
unsigned m_check_sum = 0;
unsigned m_number_of_nodes =
readHSGRFromStream(hsgr_path, node_list, edge_list, &m_check_sum);
osrm::util::SimpleLogger().Write() << "expecting " << m_number_of_nodes
<< " nodes, checksum: " << m_check_sum;
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
osrm::util::SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and "
<< edge_list.size() << " edges";
auto m_query_graph = std::make_shared<osrm::tools::QueryGraph>(node_list, edge_list);
BOOST_ASSERT_MSG(0 == node_list.size(), "node list not flushed");
BOOST_ASSERT_MSG(0 == edge_list.size(), "edge list not flushed");
osrm::util::Percent progress(m_query_graph->GetNumberOfNodes());
for (const auto node_u : osrm::util::irange(0u, m_query_graph->GetNumberOfNodes()))
{
for (const auto eid : m_query_graph->GetAdjacentEdgeRange(node_u))
{
osrm::util::SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " <file.hsgr>";
return 1;
}
boost::filesystem::path hsgr_path(argv[1]);
std::vector<osrm::tools::QueryGraph::NodeArrayEntry> node_list;
std::vector<osrm::tools::QueryGraph::EdgeArrayEntry> edge_list;
osrm::util::SimpleLogger().Write() << "loading graph from " << hsgr_path.string();
unsigned m_check_sum = 0;
unsigned m_number_of_nodes =
readHSGRFromStream(hsgr_path, node_list, edge_list, &m_check_sum);
osrm::util::SimpleLogger().Write() << "expecting " << m_number_of_nodes
<< " nodes, checksum: " << m_check_sum;
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
osrm::util::SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and "
<< edge_list.size() << " edges";
auto m_query_graph = std::make_shared<osrm::tools::QueryGraph>(node_list, edge_list);
BOOST_ASSERT_MSG(0 == node_list.size(), "node list not flushed");
BOOST_ASSERT_MSG(0 == edge_list.size(), "edge list not flushed");
osrm::util::Percent progress(m_query_graph->GetNumberOfNodes());
for (const auto node_u : osrm::util::irange(0u, m_query_graph->GetNumberOfNodes()))
{
for (const auto eid : m_query_graph->GetAdjacentEdgeRange(node_u))
const osrm::tools::EdgeData &data = m_query_graph->GetEdgeData(eid);
if (!data.shortcut)
{
const osrm::tools::EdgeData &data = m_query_graph->GetEdgeData(eid);
if (!data.shortcut)
{
continue;
}
const unsigned node_v = m_query_graph->GetTarget(eid);
const EdgeID edge_id_1 = m_query_graph->FindEdgeInEitherDirection(node_u, data.id);
if (SPECIAL_EDGEID == edge_id_1)
{
throw osrm::util::exception(
"cannot find first segment of edge (" + std::to_string(node_u) + "," +
std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " +
std::to_string(eid));
}
const EdgeID edge_id_2 = m_query_graph->FindEdgeInEitherDirection(data.id, node_v);
if (SPECIAL_EDGEID == edge_id_2)
{
throw osrm::util::exception(
"cannot find second segment of edge (" + std::to_string(node_u) + "," +
std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " +
std::to_string(eid));
}
continue;
}
const unsigned node_v = m_query_graph->GetTarget(eid);
const EdgeID edge_id_1 = m_query_graph->FindEdgeInEitherDirection(node_u, data.id);
if (SPECIAL_EDGEID == edge_id_1)
{
throw osrm::util::exception(
"cannot find first segment of edge (" + std::to_string(node_u) + "," +
std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " +
std::to_string(eid));
}
const EdgeID edge_id_2 = m_query_graph->FindEdgeInEitherDirection(data.id, node_v);
if (SPECIAL_EDGEID == edge_id_2)
{
throw osrm::util::exception(
"cannot find second segment of edge (" + std::to_string(node_u) + "," +
std::to_string(data.id) + "," + std::to_string(node_v) + "), eid: " +
std::to_string(eid));
}
progress.printStatus(node_u);
}
m_query_graph.reset();
osrm::util::SimpleLogger().Write() << "Data file " << argv[0] << " appears to be OK";
progress.printStatus(node_u);
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
m_query_graph.reset();
osrm::util::SimpleLogger().Write() << "Data file " << argv[0] << " appears to be OK";
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return EXIT_FAILURE;
}
+118 -120
View File
@@ -98,141 +98,139 @@ std::size_t loadGraph(const char *path,
}
}
int main(int argc, char *argv[])
int main(int argc, char *argv[]) try
{
std::vector<osrm::extractor::QueryNode> coordinate_list;
osrm::util::LogPolicy::GetInstance().Unmute();
try
// enable logging
if (argc < 2)
{
// enable logging
if (argc < 2)
osrm::util::SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] << " <osrm>";
return EXIT_FAILURE;
}
std::vector<osrm::tools::TarjanEdge> graph_edge_list;
auto number_of_nodes = osrm::tools::loadGraph(argv[1], coordinate_list, graph_edge_list);
tbb::parallel_sort(graph_edge_list.begin(), graph_edge_list.end());
const auto graph =
std::make_shared<osrm::tools::TarjanGraph>(number_of_nodes, graph_edge_list);
graph_edge_list.clear();
graph_edge_list.shrink_to_fit();
osrm::util::SimpleLogger().Write() << "Starting SCC graph traversal";
auto tarjan =
osrm::util::make_unique<osrm::extractor::TarjanSCC<osrm::tools::TarjanGraph>>(graph);
tarjan->run();
osrm::util::SimpleLogger().Write() << "identified: " << tarjan->get_number_of_components()
<< " many components";
osrm::util::SimpleLogger().Write() << "identified " << tarjan->get_size_one_count()
<< " size 1 SCCs";
// output
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
osrm::tools::deleteFileIfExists("component.dbf");
osrm::tools::deleteFileIfExists("component.shx");
osrm::tools::deleteFileIfExists("component.shp");
osrm::util::Percent percentage(graph->GetNumberOfNodes());
OGRRegisterAll();
const char *psz_driver_name = "ESRI Shapefile";
auto *po_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(psz_driver_name);
if (nullptr == po_driver)
{
throw osrm::util::exception("ESRI Shapefile driver not available");
}
auto *po_datasource = po_driver->CreateDataSource("component.shp", nullptr);
if (nullptr == po_datasource)
{
throw osrm::util::exception("Creation of output file failed");
}
auto *po_srs = new OGRSpatialReference();
po_srs->importFromEPSG(4326);
auto *po_layer = po_datasource->CreateLayer("component", po_srs, wkbLineString, nullptr);
if (nullptr == po_layer)
{
throw osrm::util::exception("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
osrm::util::SimpleLogger().Write() << "shapefile setup took "
<< TIMER_MSEC(SCC_RUN_SETUP) / 1000. << "s";
uint64_t total_network_length = 0;
percentage.reinit(graph->GetNumberOfNodes());
TIMER_START(SCC_OUTPUT);
for (const NodeID source : osrm::util::irange(0u, graph->GetNumberOfNodes()))
{
percentage.printIncrement();
for (const auto current_edge : graph->GetAdjacentEdgeRange(source))
{
osrm::util::SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] << " <osrm>";
return -1;
}
const auto target = graph->GetTarget(current_edge);
std::vector<osrm::tools::TarjanEdge> graph_edge_list;
auto number_of_nodes = osrm::tools::loadGraph(argv[1], coordinate_list, graph_edge_list);
tbb::parallel_sort(graph_edge_list.begin(), graph_edge_list.end());
const auto graph =
std::make_shared<osrm::tools::TarjanGraph>(number_of_nodes, graph_edge_list);
graph_edge_list.clear();
graph_edge_list.shrink_to_fit();
osrm::util::SimpleLogger().Write() << "Starting SCC graph traversal";
auto tarjan =
osrm::util::make_unique<osrm::extractor::TarjanSCC<osrm::tools::TarjanGraph>>(graph);
tarjan->run();
osrm::util::SimpleLogger().Write() << "identified: " << tarjan->get_number_of_components()
<< " many components";
osrm::util::SimpleLogger().Write() << "identified " << tarjan->get_size_one_count()
<< " size 1 SCCs";
// output
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
osrm::tools::deleteFileIfExists("component.dbf");
osrm::tools::deleteFileIfExists("component.shx");
osrm::tools::deleteFileIfExists("component.shp");
osrm::util::Percent percentage(graph->GetNumberOfNodes());
OGRRegisterAll();
const char *psz_driver_name = "ESRI Shapefile";
auto *po_driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(psz_driver_name);
if (nullptr == po_driver)
{
throw osrm::util::exception("ESRI Shapefile driver not available");
}
auto *po_datasource = po_driver->CreateDataSource("component.shp", nullptr);
if (nullptr == po_datasource)
{
throw osrm::util::exception("Creation of output file failed");
}
auto *po_srs = new OGRSpatialReference();
po_srs->importFromEPSG(4326);
auto *po_layer = po_datasource->CreateLayer("component", po_srs, wkbLineString, nullptr);
if (nullptr == po_layer)
{
throw osrm::util::exception("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
osrm::util::SimpleLogger().Write() << "shapefile setup took "
<< TIMER_MSEC(SCC_RUN_SETUP) / 1000. << "s";
uint64_t total_network_length = 0;
percentage.reinit(graph->GetNumberOfNodes());
TIMER_START(SCC_OUTPUT);
for (const NodeID source : osrm::util::irange(0u, graph->GetNumberOfNodes()))
{
percentage.printIncrement();
for (const auto current_edge : graph->GetAdjacentEdgeRange(source))
if (source < target || SPECIAL_EDGEID == graph->FindEdge(target, source))
{
const auto target = graph->GetTarget(current_edge);
total_network_length +=
100 * osrm::util::coordinate_calculation::greatCircleDistance(
coordinate_list[source].lat, coordinate_list[source].lon,
coordinate_list[target].lat, coordinate_list[target].lon);
if (source < target || SPECIAL_EDGEID == graph->FindEdge(target, source))
BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
BOOST_ASSERT(source != SPECIAL_NODEID);
BOOST_ASSERT(target != SPECIAL_NODEID);
const unsigned size_of_containing_component =
std::min(tarjan->get_component_size(tarjan->get_component_id(source)),
tarjan->get_component_size(tarjan->get_component_id(target)));
// edges that end on bollard nodes may actually be in two distinct components
if (size_of_containing_component < 1000)
{
total_network_length +=
100 * osrm::util::coordinate_calculation::greatCircleDistance(
coordinate_list[source].lat, coordinate_list[source].lon,
coordinate_list[target].lat, coordinate_list[target].lon);
OGRLineString line_string;
line_string.addPoint(
coordinate_list[source].lon / osrm::COORDINATE_PRECISION,
coordinate_list[source].lat / osrm::COORDINATE_PRECISION);
line_string.addPoint(
coordinate_list[target].lon / osrm::COORDINATE_PRECISION,
coordinate_list[target].lat / osrm::COORDINATE_PRECISION);
BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
BOOST_ASSERT(source != SPECIAL_NODEID);
BOOST_ASSERT(target != SPECIAL_NODEID);
OGRFeature *po_feature =
OGRFeature::CreateFeature(po_layer->GetLayerDefn());
const unsigned size_of_containing_component =
std::min(tarjan->get_component_size(tarjan->get_component_id(source)),
tarjan->get_component_size(tarjan->get_component_id(target)));
// edges that end on bollard nodes may actually be in two distinct components
if (size_of_containing_component < 1000)
po_feature->SetGeometry(&line_string);
if (OGRERR_NONE != po_layer->CreateFeature(po_feature))
{
OGRLineString line_string;
line_string.addPoint(
coordinate_list[source].lon / osrm::COORDINATE_PRECISION,
coordinate_list[source].lat / osrm::COORDINATE_PRECISION);
line_string.addPoint(
coordinate_list[target].lon / osrm::COORDINATE_PRECISION,
coordinate_list[target].lat / osrm::COORDINATE_PRECISION);
OGRFeature *po_feature =
OGRFeature::CreateFeature(po_layer->GetLayerDefn());
po_feature->SetGeometry(&line_string);
if (OGRERR_NONE != po_layer->CreateFeature(po_feature))
{
throw osrm::util::exception("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(po_feature);
throw osrm::util::exception("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(po_feature);
}
}
}
OGRSpatialReference::DestroySpatialReference(po_srs);
OGRDataSource::DestroyDataSource(po_datasource);
TIMER_STOP(SCC_OUTPUT);
osrm::util::SimpleLogger().Write()
<< "generating output took: " << TIMER_MSEC(SCC_OUTPUT) / 1000. << "s";
osrm::util::SimpleLogger().Write()
<< "total network distance: "
<< static_cast<uint64_t>(total_network_length / 100 / 1000.) << " km";
osrm::util::SimpleLogger().Write() << "finished component analysis";
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
OGRSpatialReference::DestroySpatialReference(po_srs);
OGRDataSource::DestroyDataSource(po_datasource);
TIMER_STOP(SCC_OUTPUT);
osrm::util::SimpleLogger().Write()
<< "generating output took: " << TIMER_MSEC(SCC_OUTPUT) / 1000. << "s";
osrm::util::SimpleLogger().Write()
<< "total network distance: "
<< static_cast<uint64_t>(total_network_length / 100 / 1000.) << " km";
osrm::util::SimpleLogger().Write() << "finished component analysis";
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return EXIT_FAILURE;
}
+117 -8
View File
@@ -1,7 +1,10 @@
#include "contractor/processing_chain.hpp"
#include "contractor/contractor_options.hpp"
#include "contractor/contractor.hpp"
#include "contractor/contractor_config.hpp"
#include "util/simple_logger.hpp"
#include "util/version.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/program_options/errors.hpp>
#include <tbb/task_scheduler_init.h>
@@ -13,25 +16,131 @@
using namespace osrm;
enum class return_code : unsigned
{
ok,
fail,
exit
};
return_code
parseArguments(int argc, char *argv[], contractor::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()(
"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")(
"core,k",
boost::program_options::value<double>(&contractor_config.core_factor)->default_value(1.0),
"Percentage of the graph (in vertices) to contract [0..1]")(
"segment-speed-file",
boost::program_options::value<std::string>(&contractor_config.segment_speed_lookup_path),
"Lookup file containing nodeA,nodeB,speed data to adjust edge weights")(
"level-cache,o", boost::program_options::value<bool>(&contractor_config.use_cached_priority)
->default_value(false),
"Use .level file to retain the contaction level for each node from the last run.");
#ifdef DEBUG_GEOMETRY
config_options.add_options()(
"debug-geometry",
boost::program_options::value<std::string>(&contractor_config.debug_geometry_path),
"Write out edge-weight debugging geometry data in GeoJSON format to this file");
#endif
// 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"))
{
util::SimpleLogger().Write() << OSRM_VERSION;
return return_code::exit;
}
if (option_variables.count("help"))
{
util::SimpleLogger().Write() << "\n" << visible_options;
return return_code::exit;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("input"))
{
util::SimpleLogger().Write() << "\n" << visible_options;
return return_code::fail;
}
return return_code::ok;
}
int main(int argc, char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
contractor::ContractorConfig contractor_config;
const contractor::return_code result =
contractor::ContractorOptions::ParseArguments(argc, argv, contractor_config);
const return_code result = parseArguments(argc, argv, contractor_config);
if (contractor::return_code::fail == result)
if (return_code::fail == result)
{
return EXIT_FAILURE;
}
if (contractor::return_code::exit == result)
if (return_code::exit == result)
{
return EXIT_SUCCESS;
}
contractor::ContractorOptions::GenerateOutputFilesNames(contractor_config);
contractor_config.UseDefaultOutputNames();
if (1 > contractor_config.requested_num_threads)
{
@@ -70,7 +179,7 @@ int main(int argc, char *argv[]) try
tbb::task_scheduler_init init(contractor_config.requested_num_threads);
return contractor::Prepare(contractor_config).Run();
return contractor::Contractor(contractor_config).Run();
}
catch (const std::bad_alloc &e)
{
-592
View File
@@ -1,592 +0,0 @@
#include "extractor/original_edge_data.hpp"
#include "util/range_table.hpp"
#include "contractor/query_edge.hpp"
#include "extractor/query_node.hpp"
#include "datastore/shared_memory_factory.hpp"
#include "util/shared_memory_vector_wrapper.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"
#include "engine/datafacade/datafacade_base.hpp"
#include "extractor/travel_mode.hpp"
#include "extractor/turn_instructions.hpp"
#include "engine/datafacade/shared_datatype.hpp"
#include "engine/datafacade/shared_barriers.hpp"
#include "util/datastore_options.hpp"
#include "util/fingerprint.hpp"
#include "util/osrm_exception.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
#include "osrm/coordinate.hpp"
#ifdef __linux__
#include <sys/mman.h>
#endif
#include <boost/filesystem/fstream.hpp>
#include <boost/iostreams/seek.hpp>
#include <cstdint>
#include <fstream>
#include <new>
#include <string>
// FIXME remove after move to datastore
using namespace osrm::engine::datafacade;
using namespace osrm::datastore;
using namespace osrm;
using RTreeLeaf =
typename engine::datafacade::BaseDataFacade<contractor::QueryEdge::EdgeData>::RTreeLeaf;
using RTreeNode = util::StaticRTree<RTreeLeaf,
util::ShM<util::FixedPointCoordinate, true>::vector,
true>::TreeNode;
using QueryGraph = util::StaticGraph<contractor::QueryEdge::EdgeData>;
namespace osrm
{
namespace tools
{
// delete a shared memory region. report warning if it could not be deleted
void deleteRegion(const SharedDataType region)
{
if (SharedMemory::RegionExists(region) && !SharedMemory::Remove(region))
{
const std::string name = [&]
{
switch (region)
{
case CURRENT_REGIONS:
return "CURRENT_REGIONS";
case LAYOUT_1:
return "LAYOUT_1";
case DATA_1:
return "DATA_1";
case LAYOUT_2:
return "LAYOUT_2";
case DATA_2:
return "DATA_2";
case LAYOUT_NONE:
return "LAYOUT_NONE";
default: // DATA_NONE:
return "DATA_NONE";
}
}();
util::SimpleLogger().Write(logWARNING) << "could not delete shared memory region " << name;
}
}
}
}
int main(const int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
SharedBarriers barrier;
#ifdef __linux__
// try to disable swapping on Linux
const bool lock_flags = MCL_CURRENT | MCL_FUTURE;
if (-1 == mlockall(lock_flags))
{
util::SimpleLogger().Write(logWARNING) << "Process " << argv[0]
<< " could not request RAM lock";
}
#endif
try
{
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
barrier.pending_update_mutex);
}
catch (...)
{
// hard unlock in case of any exception.
barrier.pending_update_mutex.unlock();
}
util::SimpleLogger().Write(logDEBUG) << "Checking input parameters";
std::unordered_map<std::string, boost::filesystem::path> server_paths;
if (!util::GenerateDataStoreOptions(argc, argv, server_paths))
{
return EXIT_SUCCESS;
}
if (server_paths.find("hsgrdata") == server_paths.end())
{
throw util::exception("no hsgr file found");
}
if (server_paths.find("ramindex") == server_paths.end())
{
throw util::exception("no ram index file found");
}
if (server_paths.find("fileindex") == server_paths.end())
{
throw util::exception("no leaf index file found");
}
if (server_paths.find("nodesdata") == server_paths.end())
{
throw util::exception("no nodes file found");
}
if (server_paths.find("edgesdata") == server_paths.end())
{
throw util::exception("no edges file found");
}
if (server_paths.find("namesdata") == server_paths.end())
{
throw util::exception("no names file found");
}
if (server_paths.find("geometry") == server_paths.end())
{
throw util::exception("no geometry file found");
}
if (server_paths.find("core") == server_paths.end())
{
throw util::exception("no core file found");
}
auto paths_iterator = server_paths.find("hsgrdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &hsgr_path = paths_iterator->second;
paths_iterator = server_paths.find("timestamp");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &timestamp_path = paths_iterator->second;
paths_iterator = server_paths.find("ramindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &ram_index_path = paths_iterator->second;
paths_iterator = server_paths.find("fileindex");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path index_file_path_absolute =
boost::filesystem::canonical(paths_iterator->second);
const std::string &file_index_path = index_file_path_absolute.string();
paths_iterator = server_paths.find("nodesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
paths_iterator = server_paths.find("edgesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &edges_data_path = paths_iterator->second;
paths_iterator = server_paths.find("namesdata");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &names_data_path = paths_iterator->second;
paths_iterator = server_paths.find("geometry");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &geometries_data_path = paths_iterator->second;
paths_iterator = server_paths.find("core");
BOOST_ASSERT(server_paths.end() != paths_iterator);
BOOST_ASSERT(!paths_iterator->second.empty());
const boost::filesystem::path &core_marker_path = paths_iterator->second;
// determine segment to use
bool segment2_in_use = SharedMemory::RegionExists(LAYOUT_2);
const engine::datafacade::SharedDataType layout_region = [&]
{
return segment2_in_use ? LAYOUT_1 : LAYOUT_2;
}();
const engine::datafacade::SharedDataType data_region = [&]
{
return segment2_in_use ? DATA_1 : DATA_2;
}();
const engine::datafacade::SharedDataType previous_layout_region = [&]
{
return segment2_in_use ? LAYOUT_2 : LAYOUT_1;
}();
const engine::datafacade::SharedDataType previous_data_region = [&]
{
return segment2_in_use ? DATA_2 : DATA_1;
}();
// Allocate a memory layout in shared memory, deallocate previous
auto *layout_memory = SharedMemoryFactory::Get(layout_region, sizeof(SharedDataLayout));
auto shared_layout_ptr = new (layout_memory->Ptr()) SharedDataLayout();
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::FILE_INDEX_PATH,
file_index_path.length() + 1);
// collect number of elements to store in shared memory object
util::SimpleLogger().Write() << "load names from: " << names_data_path;
// number of entries in name index
boost::filesystem::ifstream name_stream(names_data_path, std::ios::binary);
unsigned name_blocks = 0;
name_stream.read((char *)&name_blocks, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_OFFSETS, name_blocks);
shared_layout_ptr->SetBlockSize<typename util::RangeTable<16, true>::BlockT>(
SharedDataLayout::NAME_BLOCKS, name_blocks);
util::SimpleLogger().Write() << "name offsets size: " << name_blocks;
BOOST_ASSERT_MSG(0 != name_blocks, "name file broken");
unsigned number_of_chars = 0;
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
// Loading information for original edges
boost::filesystem::ifstream edges_input_stream(edges_data_path, std::ios::binary);
unsigned number_of_original_edges = 0;
edges_input_stream.read((char *)&number_of_original_edges, sizeof(unsigned));
// note: settings this all to the same size is correct, we extract them from the same struct
shared_layout_ptr->SetBlockSize<NodeID>(SharedDataLayout::VIA_NODE_LIST,
number_of_original_edges);
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_ID_LIST,
number_of_original_edges);
shared_layout_ptr->SetBlockSize<extractor::TravelMode>(SharedDataLayout::TRAVEL_MODE,
number_of_original_edges);
shared_layout_ptr->SetBlockSize<extractor::TurnInstruction>(SharedDataLayout::TURN_INSTRUCTION,
number_of_original_edges);
// note: there are 32 geometry indicators in one unsigned block
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_INDICATORS,
number_of_original_edges);
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
util::FingerPrint fingerprint_valid = util::FingerPrint::GetValid();
util::FingerPrint fingerprint_loaded;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(util::FingerPrint));
if (fingerprint_loaded.TestGraphUtil(fingerprint_valid))
{
util::SimpleLogger().Write(logDEBUG) << "Fingerprint checked out ok";
}
else
{
util::SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build. "
"Reprocess to get rid of this warning.";
}
// load checksum
unsigned checksum = 0;
hsgr_input_stream.read((char *)&checksum, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::HSGR_CHECKSUM, 1);
// load graph node size
unsigned number_of_graph_nodes = 0;
hsgr_input_stream.read((char *)&number_of_graph_nodes, sizeof(unsigned));
BOOST_ASSERT_MSG((0 != number_of_graph_nodes), "number of nodes is zero");
shared_layout_ptr->SetBlockSize<QueryGraph::NodeArrayEntry>(SharedDataLayout::GRAPH_NODE_LIST,
number_of_graph_nodes);
// load graph edge size
unsigned number_of_graph_edges = 0;
hsgr_input_stream.read((char *)&number_of_graph_edges, sizeof(unsigned));
// BOOST_ASSERT_MSG(0 != number_of_graph_edges, "number of graph edges is zero");
shared_layout_ptr->SetBlockSize<QueryGraph::EdgeArrayEntry>(SharedDataLayout::GRAPH_EDGE_LIST,
number_of_graph_edges);
// load rsearch tree size
boost::filesystem::ifstream tree_node_file(ram_index_path, std::ios::binary);
uint32_t tree_size = 0;
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
shared_layout_ptr->SetBlockSize<RTreeNode>(SharedDataLayout::R_SEARCH_TREE, tree_size);
// load timestamp size
std::string m_timestamp;
if (boost::filesystem::exists(timestamp_path))
{
boost::filesystem::ifstream timestamp_stream(timestamp_path);
if (!timestamp_stream)
{
util::SimpleLogger().Write(logWARNING) << timestamp_path
<< " not found. setting to default";
}
else
{
getline(timestamp_stream, m_timestamp);
timestamp_stream.close();
}
}
if (m_timestamp.empty())
{
m_timestamp = "n/a";
}
if (25 < m_timestamp.length())
{
m_timestamp.resize(25);
}
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::TIMESTAMP, m_timestamp.length());
// load core marker size
boost::filesystem::ifstream core_marker_file(core_marker_path, std::ios::binary);
uint32_t number_of_core_markers = 0;
core_marker_file.read((char *)&number_of_core_markers, sizeof(uint32_t));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::CORE_MARKER,
number_of_core_markers);
// load coordinate size
boost::filesystem::ifstream nodes_input_stream(nodes_data_path, std::ios::binary);
unsigned coordinate_list_size = 0;
nodes_input_stream.read((char *)&coordinate_list_size, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<util::FixedPointCoordinate>(SharedDataLayout::COORDINATE_LIST,
coordinate_list_size);
// load geometries sizes
std::ifstream geometry_input_stream(geometries_data_path.string().c_str(), std::ios::binary);
unsigned number_of_geometries_indices = 0;
unsigned number_of_compressed_geometries = 0;
geometry_input_stream.read((char *)&number_of_geometries_indices, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_INDEX,
number_of_geometries_indices);
boost::iostreams::seek(geometry_input_stream, number_of_geometries_indices * sizeof(unsigned),
BOOST_IOS::cur);
geometry_input_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned));
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_LIST,
number_of_compressed_geometries);
// allocate shared memory block
util::SimpleLogger().Write() << "allocating shared memory of "
<< shared_layout_ptr->GetSizeOfLayout() << " bytes";
SharedMemory *shared_memory =
SharedMemoryFactory::Get(data_region, shared_layout_ptr->GetSizeOfLayout());
char *shared_memory_ptr = static_cast<char *>(shared_memory->Ptr());
// read actual data into shared memory object //
// hsgr checksum
unsigned *checksum_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::HSGR_CHECKSUM);
*checksum_ptr = checksum;
// ram index file name
char *file_index_path_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
shared_memory_ptr, SharedDataLayout::FILE_INDEX_PATH);
// make sure we have 0 ending
std::fill(file_index_path_ptr,
file_index_path_ptr +
shared_layout_ptr->GetBlockSize(SharedDataLayout::FILE_INDEX_PATH),
0);
std::copy(file_index_path.begin(), file_index_path.end(), file_index_path_ptr);
// Loading street names
unsigned *name_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::NAME_OFFSETS);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_OFFSETS) > 0)
{
name_stream.read((char *)name_offsets_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_OFFSETS));
}
unsigned *name_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::NAME_BLOCKS);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_BLOCKS) > 0)
{
name_stream.read((char *)name_blocks_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_BLOCKS));
}
char *name_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
shared_memory_ptr, SharedDataLayout::NAME_CHAR_LIST);
unsigned temp_length;
name_stream.read((char *)&temp_length, sizeof(unsigned));
BOOST_ASSERT_MSG(temp_length ==
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST),
"Name file corrupted!");
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST) > 0)
{
name_stream.read(name_char_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST));
}
name_stream.close();
// load original edge information
NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr<NodeID, true>(
shared_memory_ptr, SharedDataLayout::VIA_NODE_LIST);
unsigned *name_id_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::NAME_ID_LIST);
extractor::TravelMode *travel_mode_ptr =
shared_layout_ptr->GetBlockPtr<extractor::TravelMode, true>(shared_memory_ptr,
SharedDataLayout::TRAVEL_MODE);
extractor::TurnInstruction *turn_instructions_ptr =
shared_layout_ptr->GetBlockPtr<extractor::TurnInstruction, true>(
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
unsigned *geometries_indicator_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::GEOMETRIES_INDICATORS);
extractor::OriginalEdgeData current_edge_data;
for (unsigned i = 0; i < number_of_original_edges; ++i)
{
edges_input_stream.read((char *)&(current_edge_data), sizeof(extractor::OriginalEdgeData));
via_node_ptr[i] = current_edge_data.via_node;
name_id_ptr[i] = current_edge_data.name_id;
travel_mode_ptr[i] = current_edge_data.travel_mode;
turn_instructions_ptr[i] = current_edge_data.turn_instruction;
const unsigned bucket = i / 32;
const unsigned offset = i % 32;
const unsigned value = [&]
{
unsigned return_value = 0;
if (0 != offset)
{
return_value = geometries_indicator_ptr[bucket];
}
return return_value;
}();
if (current_edge_data.compressed_geometry)
{
geometries_indicator_ptr[bucket] = (value | (1 << offset));
}
}
edges_input_stream.close();
// load compressed geometry
unsigned temporary_value;
unsigned *geometries_index_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::GEOMETRIES_INDEX);
geometry_input_stream.seekg(0, geometry_input_stream.beg);
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
BOOST_ASSERT(temporary_value ==
shared_layout_ptr->num_entries[SharedDataLayout::GEOMETRIES_INDEX]);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_INDEX) > 0)
{
geometry_input_stream.read(
(char *)geometries_index_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_INDEX));
}
unsigned *geometries_list_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::GEOMETRIES_LIST);
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
BOOST_ASSERT(temporary_value ==
shared_layout_ptr->num_entries[SharedDataLayout::GEOMETRIES_LIST]);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_LIST) > 0)
{
geometry_input_stream.read(
(char *)geometries_list_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_LIST));
}
// Loading list of coordinates
util::FixedPointCoordinate *coordinates_ptr =
shared_layout_ptr->GetBlockPtr<util::FixedPointCoordinate, true>(
shared_memory_ptr, SharedDataLayout::COORDINATE_LIST);
extractor::QueryNode current_node;
for (unsigned i = 0; i < coordinate_list_size; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(extractor::QueryNode));
coordinates_ptr[i] = util::FixedPointCoordinate(current_node.lat, current_node.lon);
}
nodes_input_stream.close();
// store timestamp
char *timestamp_ptr =
shared_layout_ptr->GetBlockPtr<char, true>(shared_memory_ptr, SharedDataLayout::TIMESTAMP);
std::copy(m_timestamp.c_str(), m_timestamp.c_str() + m_timestamp.length(), timestamp_ptr);
// store search tree portion of rtree
char *rtree_ptr = shared_layout_ptr->GetBlockPtr<char, true>(shared_memory_ptr,
SharedDataLayout::R_SEARCH_TREE);
if (tree_size > 0)
{
tree_node_file.read(rtree_ptr, sizeof(RTreeNode) * tree_size);
}
tree_node_file.close();
// load core markers
std::vector<char> unpacked_core_markers(number_of_core_markers);
core_marker_file.read((char *)unpacked_core_markers.data(),
sizeof(char) * number_of_core_markers);
unsigned *core_marker_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::CORE_MARKER);
for (auto i = 0u; i < number_of_core_markers; ++i)
{
BOOST_ASSERT(unpacked_core_markers[i] == 0 || unpacked_core_markers[i] == 1);
if (unpacked_core_markers[i] == 1)
{
const unsigned bucket = i / 32;
const unsigned offset = i % 32;
const unsigned value = [&]
{
unsigned return_value = 0;
if (0 != offset)
{
return_value = core_marker_ptr[bucket];
}
return return_value;
}();
core_marker_ptr[bucket] = (value | (1 << offset));
}
}
// load the nodes of the search graph
QueryGraph::NodeArrayEntry *graph_node_list_ptr =
shared_layout_ptr->GetBlockPtr<QueryGraph::NodeArrayEntry, true>(
shared_memory_ptr, SharedDataLayout::GRAPH_NODE_LIST);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_NODE_LIST) > 0)
{
hsgr_input_stream.read((char *)graph_node_list_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_NODE_LIST));
}
// load the edges of the search graph
QueryGraph::EdgeArrayEntry *graph_edge_list_ptr =
shared_layout_ptr->GetBlockPtr<QueryGraph::EdgeArrayEntry, true>(
shared_memory_ptr, SharedDataLayout::GRAPH_EDGE_LIST);
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_EDGE_LIST) > 0)
{
hsgr_input_stream.read((char *)graph_edge_list_ptr,
shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_EDGE_LIST));
}
hsgr_input_stream.close();
// acquire lock
SharedMemory *data_type_memory =
SharedMemoryFactory::Get(CURRENT_REGIONS, sizeof(SharedDataTimestamp), true, false);
SharedDataTimestamp *data_timestamp_ptr =
static_cast<SharedDataTimestamp *>(data_type_memory->Ptr());
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
barrier.query_mutex);
// notify all processes that were waiting for this condition
if (0 < barrier.number_of_queries)
{
barrier.no_running_queries_condition.wait(query_lock);
}
data_timestamp_ptr->layout = layout_region;
data_timestamp_ptr->data = data_region;
data_timestamp_ptr->timestamp += 1;
tools::deleteRegion(previous_data_region);
tools::deleteRegion(previous_layout_region);
util::SimpleLogger().Write() << "all data loaded";
shared_layout_ptr->PrintInformation();
return EXIT_SUCCESS;
}
catch (const std::bad_alloc &e)
{
util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
util::SimpleLogger().Write(logWARNING)
<< "Please provide more memory or disable locking the virtual "
"address space (note: this makes OSRM swap, i.e. slow)";
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
util::SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
}
+136 -6
View File
@@ -1,8 +1,13 @@
#include "extractor/extractor.hpp"
#include "extractor/extractor_options.hpp"
#include "extractor/extractor_config.hpp"
#include "util/simple_logger.hpp"
#include "util/ini_file.hpp"
#include "util/version.hpp"
#include <tbb/task_scheduler_init.h>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <cstdlib>
#include <exception>
@@ -10,25 +15,150 @@
using namespace osrm;
enum class return_code : unsigned
{
ok,
fail,
exit
};
return_code
parseArguments(int argc, char *argv[], extractor::ExtractorConfig &extractor_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")(
/*
* TODO: re-enable this
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&extractor_config.restrictions_path),
"Restrictions file in .osrm.restrictions format")(
*/
"config,c",
boost::program_options::value<boost::filesystem::path>(&extractor_config.config_file_path)
->default_value("extractor.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()(
"profile,p",
boost::program_options::value<boost::filesystem::path>(&extractor_config.profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use")(
"generate-edge-lookup",
boost::program_options::value<bool>(&extractor_config.generate_edge_lookup)
->implicit_value(true)
->default_value(false),
"Generate a lookup table for internal edge-expanded-edge IDs to OSM node pairs")(
"small-component-size",
boost::program_options::value<unsigned int>(&extractor_config.small_component_size)
->default_value(1000),
"Number of nodes required before a strongly-connected-componennt is considered big "
"(affects nearest neighbor snapping)");
#ifdef DEBUG_GEOMETRY
config_options.add_options()("debug-turns", boost::program_options::value<std::string>(
&extractor_config.debug_turns_path),
"Write out GeoJSON with turn penalty data");
#endif // DEBUG_GEOMETRY
// 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>(
&extractor_config.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(
boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
try
{
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);
if (option_variables.count("version"))
{
util::SimpleLogger().Write() << OSRM_VERSION;
return return_code::exit;
}
if (option_variables.count("help"))
{
util::SimpleLogger().Write() << visible_options;
return return_code::exit;
}
boost::program_options::notify(option_variables);
// parse config file
if (boost::filesystem::is_regular_file(extractor_config.config_file_path))
{
util::SimpleLogger().Write() << "Reading options from: "
<< extractor_config.config_file_path.string();
std::string ini_file_contents =
util::read_file_lower_content(extractor_config.config_file_path);
std::stringstream config_stream(ini_file_contents);
boost::program_options::store(parse_config_file(config_stream, config_file_options),
option_variables);
boost::program_options::notify(option_variables);
}
if (!option_variables.count("input"))
{
util::SimpleLogger().Write() << visible_options;
return return_code::exit;
}
}
catch (std::exception &e)
{
util::SimpleLogger().Write(logWARNING) << e.what();
return return_code::fail;
}
return return_code::ok;
}
int main(int argc, char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
extractor::ExtractorConfig extractor_config;
const extractor::return_code result =
extractor::ExtractorOptions::ParseArguments(argc, argv, extractor_config);
const auto result = parseArguments(argc, argv, extractor_config);
if (extractor::return_code::fail == result)
if (return_code::fail == result)
{
return EXIT_FAILURE;
}
if (extractor::return_code::exit == result)
if (return_code::exit == result)
{
return EXIT_SUCCESS;
}
extractor::ExtractorOptions::GenerateOutputFilesNames(extractor_config);
extractor_config.UseDefaultOutputNames();
if (1 > extractor_config.requested_num_threads)
{
+233 -235
View File
@@ -47,7 +47,9 @@ void runStatistics(std::vector<double> &timings_vector, Statistics &stats)
}
}
int main(int argc, char *argv[])
boost::filesystem::path test_path;
int main(int argc, char *argv[]) try
{
#ifdef __FreeBSD__
@@ -60,279 +62,275 @@ int main(int argc, char *argv[])
#else
osrm::util::LogPolicy::GetInstance().Unmute();
boost::filesystem::path test_path;
try
if (1 == argc)
{
if (1 == argc)
osrm::util::SimpleLogger().Write(logWARNING) << "usage: " << argv[0]
<< " /path/on/device";
return -1;
}
test_path = boost::filesystem::path(argv[1]);
test_path /= "osrm.tst";
osrm::util::SimpleLogger().Write(logDEBUG) << "temporary file: " << test_path.string();
// create files for testing
if (2 == argc)
{
// create file to test
if (boost::filesystem::exists(test_path))
{
osrm::util::SimpleLogger().Write(logWARNING) << "usage: " << argv[0]
<< " /path/on/device";
throw osrm::util::exception("Data file already exists");
}
int *random_array = new int[osrm::tools::NUMBER_OF_ELEMENTS];
std::generate(random_array, random_array + osrm::tools::NUMBER_OF_ELEMENTS, std::rand);
#ifdef __APPLE__
FILE *fd = fopen(test_path.string().c_str(), "w");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
TIMER_START(write_1gb);
write(fileno(fd), (char *)random_array,
osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
TIMER_STOP(write_1gb);
fclose(fd);
#endif
#ifdef __linux__
int file_desc =
open(test_path.string().c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
if (-1 == file_desc)
{
throw osrm::util::exception("Could not open random data file");
}
TIMER_START(write_1gb);
int ret =
write(file_desc, random_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
if (0 > ret)
{
throw osrm::util::exception("could not write random data file");
}
TIMER_STOP(write_1gb);
close(file_desc);
#endif
delete[] random_array;
osrm::util::SimpleLogger().Write(logDEBUG) << "writing raw 1GB took "
<< TIMER_SEC(write_1gb) << "s";
osrm::util::SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb)
<< "MB/sec";
osrm::util::SimpleLogger().Write(logDEBUG)
<< "finished creation of random data. Flush disk cache now!";
}
else
{
// Run Non-Cached I/O benchmarks
if (!boost::filesystem::exists(test_path))
{
throw osrm::util::exception("data file does not exist");
}
// volatiles do not get optimized
osrm::tools::Statistics stats;
#ifdef __APPLE__
volatile unsigned single_block[1024];
char *raw_array = new char[osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned)];
FILE *fd = fopen(test_path.string().c_str(), "r");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
#endif
#ifdef __linux__
char *single_block = (char *)memalign(512, 1024 * sizeof(unsigned));
int file_desc = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
if (-1 == file_desc)
{
osrm::util::SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
return -1;
}
test_path = boost::filesystem::path(argv[1]);
test_path /= "osrm.tst";
osrm::util::SimpleLogger().Write(logDEBUG) << "temporary file: " << test_path.string();
// create files for testing
if (2 == argc)
{
// create file to test
if (boost::filesystem::exists(test_path))
{
throw osrm::util::exception("Data file already exists");
}
int *random_array = new int[osrm::tools::NUMBER_OF_ELEMENTS];
std::generate(random_array, random_array + osrm::tools::NUMBER_OF_ELEMENTS, std::rand);
char *raw_array =
(char *)memalign(512, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
#endif
TIMER_START(read_1gb);
#ifdef __APPLE__
FILE *fd = fopen(test_path.string().c_str(), "w");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
TIMER_START(write_1gb);
write(fileno(fd), (char *)random_array,
osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
TIMER_STOP(write_1gb);
fclose(fd);
read(fileno(fd), raw_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
close(fileno(fd));
fd = fopen(test_path.string().c_str(), "r");
#endif
#ifdef __linux__
int file_desc =
open(test_path.string().c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
if (-1 == file_desc)
{
throw osrm::util::exception("Could not open random data file");
}
TIMER_START(write_1gb);
int ret =
write(file_desc, random_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
if (0 > ret)
{
throw osrm::util::exception("could not write random data file");
}
TIMER_STOP(write_1gb);
close(file_desc);
int ret =
read(file_desc, raw_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
osrm::util::SimpleLogger().Write(logDEBUG) << "read " << ret
<< " bytes, error: " << strerror(errno);
close(file_desc);
file_desc = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
osrm::util::SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
delete[] random_array;
osrm::util::SimpleLogger().Write(logDEBUG) << "writing raw 1GB took "
<< TIMER_SEC(write_1gb) << "s";
osrm::util::SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb)
<< "MB/sec";
TIMER_STOP(read_1gb);
osrm::util::SimpleLogger().Write(logDEBUG)
<< "finished creation of random data. Flush disk cache now!";
osrm::util::SimpleLogger().Write(logDEBUG) << "reading raw 1GB took "
<< TIMER_SEC(read_1gb) << "s";
osrm::util::SimpleLogger().Write() << "raw read performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / TIMER_SEC(read_1gb)
<< "MB/sec";
std::vector<double> timing_results_raw_random;
osrm::util::SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";
#ifdef __APPLE__
fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
lseek(file_desc, 0, SEEK_SET);
#endif
// make 1000 random access, time each I/O seperately
unsigned number_of_blocks =
(osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned) - 1) / 4096;
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<unsigned> uniform_dist(0, number_of_blocks - 1);
for (unsigned i = 0; i < 1000; ++i)
{
unsigned block_to_read = uniform_dist(e1);
off_t current_offset = block_to_read * 4096;
TIMER_START(random_access);
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __linux__
int ret1 = lseek(file_desc, current_offset, SEEK_SET);
int ret2 = read(file_desc, (char *)single_block, 4096);
#endif
TIMER_STOP(random_access);
if (((off_t)-1) == ret1)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "seek error "
<< strerror(errno);
throw osrm::util::exception("seek error");
}
if (-1 == ret2)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "read error "
<< strerror(errno);
throw osrm::util::exception("read error");
}
timing_results_raw_random.push_back(TIMER_SEC(random_access));
}
else
// Do statistics
osrm::util::SimpleLogger().Write(logDEBUG) << "running raw random I/O statistics";
std::ofstream random_csv("random.csv", std::ios::trunc);
for (unsigned i = 0; i < timing_results_raw_random.size(); ++i)
{
// Run Non-Cached I/O benchmarks
if (!boost::filesystem::exists(test_path))
{
throw osrm::util::exception("data file does not exist");
}
random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
}
random_csv.close();
osrm::tools::runStatistics(timing_results_raw_random, stats);
// volatiles do not get optimized
osrm::tools::Statistics stats;
osrm::util::SimpleLogger().Write() << "raw random I/O: " << std::setprecision(5)
<< std::fixed << "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
std::vector<double> timing_results_raw_seq;
#ifdef __APPLE__
volatile unsigned single_block[1024];
char *raw_array = new char[osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned)];
FILE *fd = fopen(test_path.string().c_str(), "r");
fcntl(fileno(fd), F_NOCACHE, 1);
fcntl(fileno(fd), F_RDAHEAD, 0);
fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
char *single_block = (char *)memalign(512, 1024 * sizeof(unsigned));
int file_desc = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
if (-1 == file_desc)
{
osrm::util::SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
return -1;
}
char *raw_array =
(char *)memalign(512, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
lseek(file_desc, 0, SEEK_SET);
#endif
TIMER_START(read_1gb);
// read every 100th block
for (unsigned i = 0; i < 1000; ++i)
{
off_t current_offset = i * 4096;
TIMER_START(read_every_100);
#ifdef __APPLE__
read(fileno(fd), raw_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
close(fileno(fd));
fd = fopen(test_path.string().c_str(), "r");
#endif
#ifdef __linux__
int ret =
read(file_desc, raw_array, osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned));
osrm::util::SimpleLogger().Write(logDEBUG) << "read " << ret
<< " bytes, error: " << strerror(errno);
close(file_desc);
file_desc = open(test_path.string().c_str(), O_RDONLY | O_DIRECT | O_SYNC);
osrm::util::SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
TIMER_STOP(read_1gb);
osrm::util::SimpleLogger().Write(logDEBUG) << "reading raw 1GB took "
<< TIMER_SEC(read_1gb) << "s";
osrm::util::SimpleLogger().Write() << "raw read performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / TIMER_SEC(read_1gb)
<< "MB/sec";
std::vector<double> timing_results_raw_random;
osrm::util::SimpleLogger().Write(logDEBUG) << "running 1000 random I/Os of 4KB";
#ifdef __APPLE__
fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
lseek(file_desc, 0, SEEK_SET);
#endif
// make 1000 random access, time each I/O seperately
unsigned number_of_blocks =
(osrm::tools::NUMBER_OF_ELEMENTS * sizeof(unsigned) - 1) / 4096;
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<unsigned> uniform_dist(0, number_of_blocks - 1);
for (unsigned i = 0; i < 1000; ++i)
{
unsigned block_to_read = uniform_dist(e1);
off_t current_offset = block_to_read * 4096;
TIMER_START(random_access);
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block[0], 4096);
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block, 4096);
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __linux__
int ret1 = lseek(file_desc, current_offset, SEEK_SET);
int ret2 = read(file_desc, (char *)single_block, 4096);
#endif
TIMER_STOP(random_access);
if (((off_t)-1) == ret1)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "seek error "
<< strerror(errno);
throw osrm::util::exception("seek error");
}
if (-1 == ret2)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "read error "
<< strerror(errno);
throw osrm::util::exception("read error");
}
timing_results_raw_random.push_back(TIMER_SEC(random_access));
}
int ret1 = lseek(file_desc, current_offset, SEEK_SET);
// Do statistics
osrm::util::SimpleLogger().Write(logDEBUG) << "running raw random I/O statistics";
std::ofstream random_csv("random.csv", std::ios::trunc);
for (unsigned i = 0; i < timing_results_raw_random.size(); ++i)
int ret2 = read(file_desc, (char *)single_block, 4096);
#endif
TIMER_STOP(read_every_100);
if (((off_t)-1) == ret1)
{
random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "seek error "
<< strerror(errno);
throw osrm::util::exception("seek error");
}
random_csv.close();
osrm::tools::runStatistics(timing_results_raw_random, stats);
osrm::util::SimpleLogger().Write() << "raw random I/O: " << std::setprecision(5)
<< std::fixed << "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
std::vector<double> timing_results_raw_seq;
#ifdef __APPLE__
fseek(fd, 0, SEEK_SET);
#endif
#ifdef __linux__
lseek(file_desc, 0, SEEK_SET);
#endif
// read every 100th block
for (unsigned i = 0; i < 1000; ++i)
if (-1 == ret2)
{
off_t current_offset = i * 4096;
TIMER_START(read_every_100);
#ifdef __APPLE__
int ret1 = fseek(fd, current_offset, SEEK_SET);
int ret2 = read(fileno(fd), (char *)&single_block, 4096);
#endif
#ifdef __FreeBSD__
int ret1 = 0;
int ret2 = 0;
#endif
#ifdef __linux__
int ret1 = lseek(file_desc, current_offset, SEEK_SET);
int ret2 = read(file_desc, (char *)single_block, 4096);
#endif
TIMER_STOP(read_every_100);
if (((off_t)-1) == ret1)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "seek error "
<< strerror(errno);
throw osrm::util::exception("seek error");
}
if (-1 == ret2)
{
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "read error "
<< strerror(errno);
throw osrm::util::exception("read error");
}
timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
osrm::util::SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
osrm::util::SimpleLogger().Write(logWARNING) << "read error "
<< strerror(errno);
throw osrm::util::exception("read error");
}
timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
}
#ifdef __APPLE__
fclose(fd);
// free(single_element);
free(raw_array);
fclose(fd);
// free(single_element);
free(raw_array);
// free(single_block);
#endif
#ifdef __linux__
close(file_desc);
close(file_desc);
#endif
// Do statistics
osrm::util::SimpleLogger().Write(logDEBUG) << "running sequential I/O statistics";
// print simple statistics: min, max, median, variance
std::ofstream seq_csv("sequential.csv", std::ios::trunc);
for (unsigned i = 0; i < timing_results_raw_seq.size(); ++i)
{
seq_csv << i << ", " << timing_results_raw_seq[i] << std::endl;
}
seq_csv.close();
osrm::tools::runStatistics(timing_results_raw_seq, stats);
osrm::util::SimpleLogger().Write() << "raw sequential I/O: " << std::setprecision(5)
<< std::fixed << "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
osrm::util::SimpleLogger().Write(logDEBUG) << "removing temporary files";
}
// Do statistics
osrm::util::SimpleLogger().Write(logDEBUG) << "running sequential I/O statistics";
// print simple statistics: min, max, median, variance
std::ofstream seq_csv("sequential.csv", std::ios::trunc);
for (unsigned i = 0; i < timing_results_raw_seq.size(); ++i)
{
seq_csv << i << ", " << timing_results_raw_seq[i] << std::endl;
}
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
osrm::util::SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
seq_csv.close();
osrm::tools::runStatistics(timing_results_raw_seq, stats);
osrm::util::SimpleLogger().Write() << "raw sequential I/O: " << std::setprecision(5)
<< std::fixed << "min: " << stats.min << "ms, "
<< "mean: " << stats.mean << "ms, "
<< "med: " << stats.med << "ms, "
<< "max: " << stats.max << "ms, "
<< "dev: " << stats.dev << "ms";
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
osrm::util::SimpleLogger().Write(logWARNING) << "removing temporary files";
osrm::util::SimpleLogger().Write(logDEBUG) << "removing temporary files";
}
return -1;
}
return 0;
return EXIT_SUCCESS;
#endif
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
osrm::util::SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
osrm::util::SimpleLogger().Write(logWARNING) << "removing temporary files";
}
return EXIT_FAILURE;
}
+9 -9
View File
@@ -4,7 +4,7 @@
#include "util/simple_logger.hpp"
#include "osrm/osrm.hpp"
#include "osrm/libosrm_config.hpp"
#include "osrm/engine_config.hpp"
#ifdef __linux__
#include <sys/mman.h>
@@ -49,12 +49,12 @@ int main(int argc, const char *argv[]) try
std::string ip_address;
int ip_port, requested_thread_num;
LibOSRMConfig lib_config;
EngineConfig config;
const unsigned init_result = util::GenerateServerProgramOptions(
argc, argv, lib_config.server_paths, ip_address, ip_port, requested_thread_num,
lib_config.use_shared_memory, trial_run, lib_config.max_locations_trip,
lib_config.max_locations_viaroute, lib_config.max_locations_distance_table,
lib_config.max_locations_map_matching);
argc, argv, config.server_paths, ip_address, ip_port, requested_thread_num,
config.use_shared_memory, trial_run, config.max_locations_trip,
config.max_locations_viaroute, config.max_locations_distance_table,
config.max_locations_map_matching);
if (init_result == util::INIT_OK_DO_NOT_START_ENGINE)
{
return EXIT_SUCCESS;
@@ -81,11 +81,11 @@ int main(int argc, const char *argv[]) try
(void)munlockall();
}
bool should_lock = false, could_lock = true;
} memory_locker(lib_config.use_shared_memory);
} memory_locker(config.use_shared_memory);
#endif
util::SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION;
if (lib_config.use_shared_memory)
if (config.use_shared_memory)
{
util::SimpleLogger().Write(logDEBUG) << "Loading from shared memory";
}
@@ -102,7 +102,7 @@ int main(int argc, const char *argv[]) try
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif
OSRM osrm_lib(lib_config);
OSRM osrm_lib(config);
auto routing_server = server::Server::CreateServer(ip_address, ip_port, requested_thread_num);
routing_server->GetRequestHandlerPtr().RegisterRoutingMachine(&osrm_lib);
-69
View File
@@ -1,69 +0,0 @@
#include "util/json_renderer.hpp"
#include "util/routed_options.hpp"
#include "util/simple_logger.hpp"
#include "osrm/json_container.hpp"
#include "osrm/libosrm_config.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/osrm.hpp"
#include <string>
int main(int argc, const char *argv[])
{
osrm::util::LogPolicy::GetInstance().Unmute();
try
{
std::string ip_address;
int ip_port, requested_thread_num;
bool trial_run = false;
osrm::LibOSRMConfig lib_config;
const unsigned init_result = osrm::util::GenerateServerProgramOptions(
argc, argv, lib_config.server_paths, ip_address, ip_port, requested_thread_num,
lib_config.use_shared_memory, trial_run, lib_config.max_locations_trip,
lib_config.max_locations_viaroute, lib_config.max_locations_distance_table,
lib_config.max_locations_map_matching);
if (init_result == osrm::util::INIT_OK_DO_NOT_START_ENGINE)
{
return 0;
}
if (init_result == osrm::util::INIT_FAILED)
{
return 1;
}
osrm::OSRM routing_machine(lib_config);
osrm::RouteParameters route_parameters;
route_parameters.zoom_level = 18; // no generalization
route_parameters.print_instructions = true; // turn by turn instructions
route_parameters.alternate_route = true; // get an alternate route, too
route_parameters.geometry = true; // retrieve geometry of route
route_parameters.compression = true; // polyline encoding
route_parameters.check_sum = -1; // see wiki
route_parameters.service = "viaroute"; // that's routing
route_parameters.output_format = "json";
route_parameters.jsonp_parameter = ""; // set for jsonp wrapping
route_parameters.language = ""; // unused atm
// route_parameters.hints.push_back(); // see wiki, saves I/O if done properly
// start_coordinate
route_parameters.coordinates.emplace_back(52.519930 * osrm::COORDINATE_PRECISION,
13.438640 * osrm::COORDINATE_PRECISION);
// target_coordinate
route_parameters.coordinates.emplace_back(52.513191 * osrm::COORDINATE_PRECISION,
13.415852 * osrm::COORDINATE_PRECISION);
osrm::json::Object json_result;
const int result_code = routing_machine.RunQuery(route_parameters, json_result);
osrm::util::SimpleLogger().Write() << "http code: " << result_code;
osrm::json::render(osrm::util::SimpleLogger().Write(), json_result);
}
catch (std::exception &current_exception)
{
osrm::util::SimpleLogger().Write(logWARNING) << "caught exception: "
<< current_exception.what();
return -1;
}
return 0;
}
+25 -28
View File
@@ -1,7 +1,7 @@
#include <cstdio>
#include "datastore/shared_memory_factory.hpp"
#include "engine/datafacade/shared_datatype.hpp"
#include "storage/shared_memory.hpp"
#include "storage/shared_datatype.hpp"
#include "util/simple_logger.hpp"
namespace osrm
@@ -10,8 +10,7 @@ namespace tools
{
// FIXME remove after folding back into datastore
using namespace datastore;
using namespace engine::datafacade;
using namespace storage;
void deleteRegion(const SharedDataType region)
{
@@ -55,33 +54,31 @@ void springclean()
}
}
int main()
int main() try
{
osrm::util::LogPolicy::GetInstance().Unmute();
try
{
osrm::util::SimpleLogger().Write() << "Releasing all locks";
osrm::util::SimpleLogger().Write() << "ATTENTION! BE CAREFUL!";
osrm::util::SimpleLogger().Write() << "----------------------";
osrm::util::SimpleLogger().Write()
<< "This tool may put osrm-routed into an undefined state!";
osrm::util::SimpleLogger().Write()
<< "Type 'Y' to acknowledge that you know what your are doing.";
osrm::util::SimpleLogger().Write()
<< "\n\nDo you want to purge all shared memory allocated "
<< "by osrm-datastore? [type 'Y' to confirm]";
osrm::util::SimpleLogger().Write() << "Releasing all locks";
osrm::util::SimpleLogger().Write() << "ATTENTION! BE CAREFUL!";
osrm::util::SimpleLogger().Write() << "----------------------";
osrm::util::SimpleLogger().Write()
<< "This tool may put osrm-routed into an undefined state!";
osrm::util::SimpleLogger().Write()
<< "Type 'Y' to acknowledge that you know what your are doing.";
osrm::util::SimpleLogger().Write()
<< "\n\nDo you want to purge all shared memory allocated "
<< "by osrm-datastore? [type 'Y' to confirm]";
const auto letter = getchar();
if (letter != 'Y')
{
osrm::util::SimpleLogger().Write() << "aborted.";
return 0;
}
osrm::tools::springclean();
}
catch (const std::exception &e)
const auto letter = getchar();
if (letter != 'Y')
{
osrm::util::SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
osrm::util::SimpleLogger().Write() << "aborted.";
return EXIT_SUCCESS;
}
return 0;
osrm::tools::springclean();
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
return EXIT_FAILURE;
}
+286
View File
@@ -0,0 +1,286 @@
#include "storage/storage.hpp"
#include "util/osrm_exception.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
#include "util/ini_file.hpp"
#include "util/version.hpp"
#include <boost/filesystem/path.hpp>
#include <boost/program_options.hpp>
using namespace osrm;
// generate boost::program_options object for the routing part
bool generateDataStoreOptions(const int argc,
const char *argv[],
storage::DataPaths &paths)
{
// 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")(
"springclean,s", "Remove all regions in shared memory")(
"config,c", boost::program_options::value<boost::filesystem::path>(&paths["config"])
->default_value("server.ini"),
"Path to a configuration file");
// declare a group of options that will be allowed both on command line
// as well as in a config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"hsgrdata", boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
".hsgr file")("nodesdata",
boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
".nodes file")(
"edgesdata", boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
".edges file")("geometry",
boost::program_options::value<boost::filesystem::path>(&paths["geometry"]),
".geometry file")(
"ramindex", boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
".ramIndex file")(
"fileindex", boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
".fileIndex file")("core",
boost::program_options::value<boost::filesystem::path>(&paths["core"]),
".core file")(
"namesdata", boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
".names file")("timestamp",
boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
".timestamp file");
// 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()(
"base,b", boost::program_options::value<boost::filesystem::path>(&paths["base"]),
"base path to .osrm file");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("base", 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(
boost::filesystem::basename(argv[0]) + " [<options>] <configuration>");
visible_options.add(generic_options).add(config_options);
// print help options if no infile is specified
if (argc < 2)
{
util::SimpleLogger().Write() << visible_options;
return false;
}
// 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);
if (option_variables.count("version"))
{
util::SimpleLogger().Write() << OSRM_VERSION;
return false;
}
if (option_variables.count("help"))
{
util::SimpleLogger().Write() << visible_options;
return false;
}
boost::program_options::notify(option_variables);
const bool parameter_present =
(paths.find("hsgrdata") != paths.end() &&
!paths.find("hsgrdata")->second.string().empty()) ||
(paths.find("nodesdata") != paths.end() &&
!paths.find("nodesdata")->second.string().empty()) ||
(paths.find("edgesdata") != paths.end() &&
!paths.find("edgesdata")->second.string().empty()) ||
(paths.find("geometry") != paths.end() &&
!paths.find("geometry")->second.string().empty()) ||
(paths.find("ramindex") != paths.end() &&
!paths.find("ramindex")->second.string().empty()) ||
(paths.find("fileindex") != paths.end() &&
!paths.find("fileindex")->second.string().empty()) ||
(paths.find("core") != paths.end() && !paths.find("core")->second.string().empty()) ||
(paths.find("timestamp") != paths.end() &&
!paths.find("timestamp")->second.string().empty());
if (parameter_present)
{
if ((paths.find("config") != paths.end() &&
boost::filesystem::is_regular_file(paths.find("config")->second)) ||
option_variables.count("base"))
{
util::SimpleLogger().Write(logWARNING) << "conflicting parameters";
util::SimpleLogger().Write() << visible_options;
return false;
}
}
// parse config file
auto path_iterator = paths.find("config");
if (path_iterator != paths.end() && boost::filesystem::is_regular_file(path_iterator->second) &&
!option_variables.count("base"))
{
util::SimpleLogger().Write() << "Reading options from: " << path_iterator->second.string();
std::string ini_file_contents = util::read_file_lower_content(path_iterator->second);
std::stringstream config_stream(ini_file_contents);
boost::program_options::store(parse_config_file(config_stream, config_file_options),
option_variables);
boost::program_options::notify(option_variables);
}
else if (option_variables.count("base"))
{
path_iterator = paths.find("base");
BOOST_ASSERT(paths.end() != path_iterator);
std::string base_string = path_iterator->second.string();
path_iterator = paths.find("hsgrdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".hsgr";
}
path_iterator = paths.find("nodesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".nodes";
}
path_iterator = paths.find("edgesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".edges";
}
path_iterator = paths.find("geometry");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".geometry";
}
path_iterator = paths.find("ramindex");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".ramIndex";
}
path_iterator = paths.find("fileindex");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".fileIndex";
}
path_iterator = paths.find("core");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".core";
}
path_iterator = paths.find("namesdata");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".names";
}
path_iterator = paths.find("timestamp");
if (path_iterator != paths.end())
{
path_iterator->second = base_string + ".timestamp";
}
}
path_iterator = paths.find("hsgrdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .hsgr file must be specified");
}
path_iterator = paths.find("nodesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .nodes file must be specified");
}
path_iterator = paths.find("edgesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .edges file must be specified");
}
path_iterator = paths.find("geometry");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .geometry file must be specified");
}
path_iterator = paths.find("ramindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .ramindex file must be specified");
}
path_iterator = paths.find("fileindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .fileindex file must be specified");
}
path_iterator = paths.find("namesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .names file must be specified");
}
path_iterator = paths.find("timestamp");
if (path_iterator == paths.end() || path_iterator->second.string().empty() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw util::exception("valid .timestamp file must be specified");
}
return true;
}
int main(const int argc, const char *argv[]) try
{
util::LogPolicy::GetInstance().Unmute();
storage::DataPaths paths;
if (!generateDataStoreOptions(argc, argv, paths))
{
return EXIT_SUCCESS;
}
storage::Storage storage(paths);
return storage.Run();
}
catch (const std::bad_alloc &e)
{
util::SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
util::SimpleLogger().Write(logWARNING)
<< "Please provide more memory or disable locking the virtual "
"address space (note: this makes OSRM swap, i.e. slow)";
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
util::SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
return EXIT_FAILURE;
}
+12 -14
View File
@@ -1,22 +1,20 @@
#include "util/simple_logger.hpp"
#include "engine/datafacade/shared_barriers.hpp"
#include "storage/shared_barriers.hpp"
#include <iostream>
int main()
int main() try
{
osrm::util::LogPolicy::GetInstance().Unmute();
try
{
osrm::util::SimpleLogger().Write() << "Releasing all locks";
osrm::engine::datafacade::SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
}
osrm::util::SimpleLogger().Write() << "Releasing all locks";
osrm::storage::SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
return 0;
}
catch (const std::exception &e)
{
osrm::util::SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
return EXIT_FAILURE;
}