Move files in src/ include/

This commit is contained in:
Patrick Niklaus
2016-01-02 13:55:06 +01:00
parent 758d402305
commit bfc6c9b89d
184 changed files with 0 additions and 608 deletions
+1
View File
@@ -0,0 +1 @@
/osrm-component
+112
View File
@@ -0,0 +1,112 @@
/*
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 "../data_structures/percent.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp"
#include "../util/integer_range.hpp"
#include "../util/graph_loader.hpp"
#include "../util/simple_logger.hpp"
#include "../util/osrm_exception.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <memory>
#include <vector>
using EdgeData = QueryEdge::EdgeData;
using QueryGraph = StaticGraph<EdgeData>;
int main(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
try
{
if (argc != 2)
{
SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " <file.hsgr>";
return 1;
}
boost::filesystem::path hsgr_path(argv[1]);
std::vector<QueryGraph::NodeArrayEntry> node_list;
std::vector<QueryGraph::EdgeArrayEntry> edge_list;
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);
SimpleLogger().Write() << "expecting " << m_number_of_nodes
<< " nodes, checksum: " << m_check_sum;
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and " << edge_list.size()
<< " edges";
auto m_query_graph = std::make_shared<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");
Percent progress(m_query_graph->GetNumberOfNodes());
for (const auto node_u : osrm::irange(0u, m_query_graph->GetNumberOfNodes()))
{
for (const auto eid : m_query_graph->GetAdjacentEdgeRange(node_u))
{
const 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::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::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();
SimpleLogger().Write() << "Data file " << argv[0] << " appears to be OK";
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
}
+257
View File
@@ -0,0 +1,257 @@
/*
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 "../typedefs.h"
#include "../algorithms/tarjan_scc.hpp"
#include "../algorithms/coordinate_calculation.hpp"
#include "../data_structures/dynamic_graph.hpp"
#include "../data_structures/static_graph.hpp"
#include "../util/fingerprint.hpp"
#include "../util/graph_loader.hpp"
#include "../util/make_unique.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#if defined(__APPLE__) || defined(_WIN32)
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <osrm/coordinate.hpp>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
namespace
{
struct TarjanEdgeData
{
TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {}
TarjanEdgeData(unsigned distance, unsigned name_id) : distance(distance), name_id(name_id) {}
unsigned distance;
unsigned name_id;
};
using TarjanGraph = StaticGraph<TarjanEdgeData>;
using TarjanEdge = TarjanGraph::InputEdge;
void DeleteFileIfExists(const std::string &file_name)
{
if (boost::filesystem::exists(file_name))
{
boost::filesystem::remove(file_name);
}
}
}
std::size_t LoadGraph(const char *path,
std::vector<QueryNode> &coordinate_list,
std::vector<TarjanEdge> &graph_edge_list)
{
std::ifstream input_stream(path, std::ifstream::in | std::ifstream::binary);
if (!input_stream.is_open())
{
throw osrm::exception("Cannot open osrm file");
}
// load graph data
std::vector<NodeBasedEdge> edge_list;
std::vector<NodeID> traffic_light_node_list;
std::vector<NodeID> barrier_node_list;
auto number_of_nodes = loadNodesFromFile(input_stream, barrier_node_list,
traffic_light_node_list, coordinate_list);
loadEdgesFromFile(input_stream, edge_list);
traffic_light_node_list.clear();
traffic_light_node_list.shrink_to_fit();
// Building an node-based graph
for (const auto &input_edge : edge_list)
{
if (input_edge.source == input_edge.target)
{
continue;
}
if (input_edge.forward)
{
graph_edge_list.emplace_back(input_edge.source, input_edge.target,
(std::max)(input_edge.weight, 1), input_edge.name_id);
}
if (input_edge.backward)
{
graph_edge_list.emplace_back(input_edge.target, input_edge.source,
(std::max)(input_edge.weight, 1), input_edge.name_id);
}
}
return number_of_nodes;
}
int main(int argc, char *argv[])
{
std::vector<QueryNode> coordinate_list;
LogPolicy::GetInstance().Unmute();
try
{
// enable logging
if (argc < 2)
{
SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0] << " <osrm>";
return -1;
}
std::vector<TarjanEdge> graph_edge_list;
auto number_of_nodes = 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<TarjanGraph>(number_of_nodes, graph_edge_list);
graph_edge_list.clear();
graph_edge_list.shrink_to_fit();
SimpleLogger().Write() << "Starting SCC graph traversal";
auto tarjan = osrm::make_unique<TarjanSCC<TarjanGraph>>(graph);
tarjan->run();
SimpleLogger().Write() << "identified: " << tarjan->get_number_of_components()
<< " many components";
SimpleLogger().Write() << "identified " << tarjan->get_size_one_count() << " size 1 SCCs";
// output
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent percentage(graph->GetNumberOfNodes());
OGRRegisterAll();
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
if (nullptr == poDriver)
{
throw osrm::exception("ESRI Shapefile driver not available");
}
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);
if (nullptr == poDS)
{
throw osrm::exception("Creation of output file failed");
}
OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->importFromEPSG(4326);
OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr);
if (nullptr == poLayer)
{
throw osrm::exception("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
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::irange(0u, graph->GetNumberOfNodes()))
{
percentage.printIncrement();
for (const auto current_edge : graph->GetAdjacentEdgeRange(source))
{
const TarjanGraph::NodeIterator target = graph->GetTarget(current_edge);
if (source < target || SPECIAL_EDGEID == graph->FindEdge(target, source))
{
total_network_length +=
100 * coordinate_calculation::great_circle_distance(
coordinate_list[source].lat, coordinate_list[source].lon,
coordinate_list[target].lat, coordinate_list[target].lon);
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)
{
OGRLineString lineString;
lineString.addPoint(coordinate_list[source].lon / COORDINATE_PRECISION,
coordinate_list[source].lat / COORDINATE_PRECISION);
lineString.addPoint(coordinate_list[target].lon / COORDINATE_PRECISION,
coordinate_list[target].lat / COORDINATE_PRECISION);
OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
poFeature->SetGeometry(&lineString);
if (OGRERR_NONE != poLayer->CreateFeature(poFeature))
{
throw osrm::exception("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(poFeature);
}
}
}
}
OGRSpatialReference::DestroySpatialReference(poSRS);
OGRDataSource::DestroyDataSource(poDS);
TIMER_STOP(SCC_OUTPUT);
SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT) / 1000.
<< "s";
SimpleLogger().Write() << "total network distance: "
<< static_cast<uint64_t>(total_network_length / 100 / 1000.)
<< " km";
SimpleLogger().Write() << "finished component analysis";
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
}
+109
View File
@@ -0,0 +1,109 @@
/*
Copyright (c) 2013, 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/processing_chain.hpp"
#include "contractor/contractor_options.hpp"
#include "util/simple_logger.hpp"
#include <boost/program_options/errors.hpp>
#include <tbb/task_scheduler_init.h>
#include <cstdlib>
#include <exception>
#include <ostream>
#include <new>
int main(int argc, char *argv[]) try
{
LogPolicy::GetInstance().Unmute();
ContractorConfig contractor_config;
const return_code result = ContractorOptions::ParseArguments(argc, argv, contractor_config);
if (return_code::fail == result)
{
return EXIT_FAILURE;
}
if (return_code::exit == result)
{
return EXIT_SUCCESS;
}
ContractorOptions::GenerateOutputFilesNames(contractor_config);
if (1 > contractor_config.requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return EXIT_FAILURE;
}
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 EXIT_FAILURE;
}
if (!boost::filesystem::is_regular_file(contractor_config.profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << contractor_config.profile_path.string()
<< " not found!";
return EXIT_FAILURE;
}
SimpleLogger().Write() << "Input file: "
<< contractor_config.osrm_input_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::bad_alloc &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
SimpleLogger().Write(logWARNING)
<< "Please provide more memory or consider using a larger swapfile";
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return EXIT_FAILURE;
}
+598
View File
@@ -0,0 +1,598 @@
/*
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 "data_structures/original_edge_data.hpp"
#include "data_structures/range_table.hpp"
#include "data_structures/query_edge.hpp"
#include "data_structures/query_node.hpp"
#include "data_structures/shared_memory_factory.hpp"
#include "data_structures/shared_memory_vector_wrapper.hpp"
#include "data_structures/static_graph.hpp"
#include "data_structures/static_rtree.hpp"
#include "data_structures/travel_mode.hpp"
#include "data_structures/turn_instructions.hpp"
#include "server/data_structures/datafacade_base.hpp"
#include "server/data_structures/shared_datatype.hpp"
#include "server/data_structures/shared_barriers.hpp"
#include "util/datastore_options.hpp"
#include "util/simple_logger.hpp"
#include "util/osrm_exception.hpp"
#include "util/fingerprint.hpp"
#include "typedefs.h"
#include <osrm/coordinate.hpp>
using RTreeLeaf = BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf;
using RTreeNode = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode;
using QueryGraph = StaticGraph<QueryEdge::EdgeData>;
#ifdef __linux__
#include <sys/mman.h>
#endif
#include <boost/filesystem/fstream.hpp>
#include <boost/iostreams/seek.hpp>
#include <cstdint>
#include <fstream>
#include <string>
#include <new>
// delete a shared memory region. report warning if it could not be deleted
void delete_region(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";
}
}();
SimpleLogger().Write(logWARNING) << "could not delete shared memory region " << name;
}
}
int main(const int argc, const char *argv[]) try
{
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))
{
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();
}
SimpleLogger().Write(logDEBUG) << "Checking input parameters";
std::unordered_map<std::string, boost::filesystem::path> server_paths;
if (!GenerateDataStoreOptions(argc, argv, server_paths))
{
return EXIT_SUCCESS;
}
if (server_paths.find("hsgrdata") == server_paths.end())
{
throw osrm::exception("no hsgr file found");
}
if (server_paths.find("ramindex") == server_paths.end())
{
throw osrm::exception("no ram index file found");
}
if (server_paths.find("fileindex") == server_paths.end())
{
throw osrm::exception("no leaf index file found");
}
if (server_paths.find("nodesdata") == server_paths.end())
{
throw osrm::exception("no nodes file found");
}
if (server_paths.find("edgesdata") == server_paths.end())
{
throw osrm::exception("no edges file found");
}
if (server_paths.find("namesdata") == server_paths.end())
{
throw osrm::exception("no names file found");
}
if (server_paths.find("geometry") == server_paths.end())
{
throw osrm::exception("no geometry file found");
}
if (server_paths.find("core") == server_paths.end())
{
throw osrm::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 SharedDataType layout_region = [&]
{
return segment2_in_use ? LAYOUT_1 : LAYOUT_2;
}();
const SharedDataType data_region = [&]
{
return segment2_in_use ? DATA_1 : DATA_2;
}();
const SharedDataType previous_layout_region = [&]
{
return segment2_in_use ? LAYOUT_2 : LAYOUT_1;
}();
const 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
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 RangeTable<16, true>::BlockT>(
SharedDataLayout::NAME_BLOCKS, name_blocks);
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<TravelMode>(SharedDataLayout::TRAVEL_MODE,
number_of_original_edges);
shared_layout_ptr->SetBlockSize<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);
FingerPrint fingerprint_valid = FingerPrint::GetValid();
FingerPrint fingerprint_loaded;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (fingerprint_loaded.TestGraphUtil(fingerprint_valid))
{
SimpleLogger().Write(logDEBUG) << "Fingerprint checked out ok";
}
else
{
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)
{
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<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
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);
TravelMode *travel_mode_ptr = shared_layout_ptr->GetBlockPtr<TravelMode, true>(
shared_memory_ptr, SharedDataLayout::TRAVEL_MODE);
TurnInstruction *turn_instructions_ptr = shared_layout_ptr->GetBlockPtr<TurnInstruction, true>(
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
unsigned *geometries_indicator_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
shared_memory_ptr, SharedDataLayout::GEOMETRIES_INDICATORS);
OriginalEdgeData current_edge_data;
for (unsigned i = 0; i < number_of_original_edges; ++i)
{
edges_input_stream.read((char *)&(current_edge_data), sizeof(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
FixedPointCoordinate *coordinates_ptr =
shared_layout_ptr->GetBlockPtr<FixedPointCoordinate, true>(
shared_memory_ptr, SharedDataLayout::COORDINATE_LIST);
QueryNode current_node;
for (unsigned i = 0; i < coordinate_list_size; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
coordinates_ptr[i] = 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;
delete_region(previous_data_region);
delete_region(previous_layout_region);
SimpleLogger().Write() << "all data loaded";
shared_layout_ptr->PrintInformation();
}
catch (const std::bad_alloc &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
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)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
}
+89
View File
@@ -0,0 +1,89 @@
/*
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 "extractor/extractor.hpp"
#include "extractor/extractor_options.hpp"
#include "util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <cstdlib>
#include <exception>
#include <new>
int main(int argc, char *argv[]) try
{
LogPolicy::GetInstance().Unmute();
ExtractorConfig extractor_config;
const return_code result = ExtractorOptions::ParseArguments(argc, argv, extractor_config);
if (return_code::fail == result)
{
return EXIT_FAILURE;
}
if (return_code::exit == result)
{
return EXIT_SUCCESS;
}
ExtractorOptions::GenerateOutputFilesNames(extractor_config);
if (1 > extractor_config.requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return EXIT_FAILURE;
}
if (!boost::filesystem::is_regular_file(extractor_config.input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << extractor_config.input_path.string()
<< " not found!";
return EXIT_FAILURE;
}
if (!boost::filesystem::is_regular_file(extractor_config.profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << extractor_config.profile_path.string()
<< " not found!";
return EXIT_FAILURE;
}
return extractor(extractor_config).run();
}
catch (const std::bad_alloc &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
SimpleLogger().Write(logWARNING)
<< "Please provide more memory or consider using a larger swapfile";
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return EXIT_FAILURE;
}
+348
View File
@@ -0,0 +1,348 @@
/*
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 "util/version.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <cmath>
#include <cstdio>
#include <fcntl.h>
#ifdef __linux__
#include <malloc.h>
#endif
#include <algorithm>
#include <chrono>
#include <iomanip>
#include <numeric>
#include <random>
#include <vector>
const unsigned number_of_elements = 268435456;
struct Statistics
{
double min, max, med, mean, dev;
};
void RunStatistics(std::vector<double> &timings_vector, Statistics &stats)
{
std::sort(timings_vector.begin(), timings_vector.end());
stats.min = timings_vector.front();
stats.max = timings_vector.back();
stats.med = timings_vector[timings_vector.size() / 2];
double primary_sum = std::accumulate(timings_vector.begin(), timings_vector.end(), 0.0);
stats.mean = primary_sum / timings_vector.size();
double primary_sq_sum = std::inner_product(timings_vector.begin(), timings_vector.end(),
timings_vector.begin(), 0.0);
stats.dev = std::sqrt(primary_sq_sum / timings_vector.size() - (stats.mean * stats.mean));
}
int main(int argc, char *argv[])
{
#ifdef __FreeBSD__
SimpleLogger().Write() << "Not supported on FreeBSD";
return 0;
#endif
#ifdef _WIN32
SimpleLogger().Write() << "Not supported on Windows";
return 0;
#else
LogPolicy::GetInstance().Unmute();
boost::filesystem::path test_path;
try
{
SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION;
if (1 == argc)
{
SimpleLogger().Write(logWARNING) << "usage: " << argv[0] << " /path/on/device";
return -1;
}
test_path = boost::filesystem::path(argv[1]);
test_path /= "osrm.tst";
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::exception("Data file already exists");
}
int *random_array = new int[number_of_elements];
std::generate(random_array, random_array + 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, 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::exception("Could not open random data file");
}
TIMER_START(write_1gb);
int ret = write(file_desc, random_array, number_of_elements * sizeof(unsigned));
if (0 > ret)
{
throw osrm::exception("could not write random data file");
}
TIMER_STOP(write_1gb);
close(file_desc);
#endif
delete[] random_array;
SimpleLogger().Write(logDEBUG) << "writing raw 1GB took " << TIMER_SEC(write_1gb)
<< "s";
SimpleLogger().Write() << "raw write performance: " << std::setprecision(5)
<< std::fixed << 1024 * 1024 / TIMER_SEC(write_1gb) << "MB/sec";
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::exception("data file does not exist");
}
// volatiles do not get optimized
Statistics stats;
#ifdef __APPLE__
volatile unsigned single_block[1024];
char *raw_array = new char[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)
{
SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
return -1;
}
char *raw_array = (char *)memalign(512, number_of_elements * sizeof(unsigned));
#endif
TIMER_START(read_1gb);
#ifdef __APPLE__
read(fileno(fd), raw_array, 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, number_of_elements * sizeof(unsigned));
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);
SimpleLogger().Write(logDEBUG) << "opened, error: " << strerror(errno);
#endif
TIMER_STOP(read_1gb);
SimpleLogger().Write(logDEBUG) << "reading raw 1GB took " << TIMER_SEC(read_1gb) << "s";
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;
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 = (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)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
throw osrm::exception("seek error");
}
if (-1 == ret2)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw osrm::exception("read error");
}
timing_results_raw_random.push_back(TIMER_SEC(random_access));
}
// Do statistics
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)
{
random_csv << i << ", " << timing_results_raw_random[i] << std::endl;
}
random_csv.close();
RunStatistics(timing_results_raw_random, stats);
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)
{
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)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "seek error " << strerror(errno);
throw osrm::exception("seek error");
}
if (-1 == ret2)
{
SimpleLogger().Write(logWARNING) << "offset: " << current_offset;
SimpleLogger().Write(logWARNING) << "read error " << strerror(errno);
throw osrm::exception("read error");
}
timing_results_raw_seq.push_back(TIMER_SEC(read_every_100));
}
#ifdef __APPLE__
fclose(fd);
// free(single_element);
free(raw_array);
// free(single_block);
#endif
#ifdef __linux__
close(file_desc);
#endif
// Do statistics
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();
RunStatistics(timing_results_raw_seq, stats);
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);
SimpleLogger().Write(logDEBUG) << "removing temporary files";
}
}
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
SimpleLogger().Write(logWARNING) << "cleaning up, and exiting";
if (boost::filesystem::exists(test_path))
{
boost::filesystem::remove(test_path);
SimpleLogger().Write(logWARNING) << "removing temporary files";
}
return -1;
}
return 0;
#endif
}
+198
View File
@@ -0,0 +1,198 @@
/*
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 "server/server.hpp"
#include "util/version.hpp"
#include "util/routed_options.hpp"
#include "util/simple_logger.hpp"
#include <osrm/osrm.hpp>
#include <osrm/libosrm_config.hpp>
#ifdef __linux__
#include <sys/mman.h>
#endif
#include <cstdlib>
#include <signal.h>
#include <chrono>
#include <future>
#include <iostream>
#include <thread>
#include <new>
#ifdef _WIN32
boost::function0<void> console_ctrl_function;
BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
{
switch (ctrl_type)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
console_ctrl_function();
return TRUE;
default:
return FALSE;
}
}
#endif
int main(int argc, const char *argv[]) try
{
LogPolicy::GetInstance().Unmute();
bool trial_run = false;
std::string ip_address;
int ip_port, requested_thread_num;
LibOSRMConfig lib_config;
const unsigned init_result = 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 == INIT_OK_DO_NOT_START_ENGINE)
{
return EXIT_SUCCESS;
}
if (init_result == INIT_FAILED)
{
return EXIT_FAILURE;
}
#ifdef __linux__
struct MemoryLocker final
{
explicit MemoryLocker(bool shouldLock_) : shouldLock(shouldLock_)
{
if (shouldLock && -1 == mlockall(MCL_CURRENT | MCL_FUTURE))
{
couldLock = false;
SimpleLogger().Write(logWARNING) << "memory could not be locked to RAM";
}
}
~MemoryLocker()
{
if (shouldLock && couldLock)
(void)munlockall();
}
bool shouldLock = false, couldLock = true;
} memoryLocker(lib_config.use_shared_memory);
#endif
SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION;
if (lib_config.use_shared_memory)
{
SimpleLogger().Write(logDEBUG) << "Loading from shared memory";
}
SimpleLogger().Write(logDEBUG) << "Threads:\t" << requested_thread_num;
SimpleLogger().Write(logDEBUG) << "IP address:\t" << ip_address;
SimpleLogger().Write(logDEBUG) << "IP port:\t" << ip_port;
#ifndef _WIN32
int sig = 0;
sigset_t new_mask;
sigset_t old_mask;
sigfillset(&new_mask);
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif
OSRM osrm_lib(lib_config);
auto routing_server = Server::CreateServer(ip_address, ip_port, requested_thread_num);
routing_server->GetRequestHandlerPtr().RegisterRoutingMachine(&osrm_lib);
if (trial_run)
{
SimpleLogger().Write() << "trial run, quitting after successful initialization";
}
else
{
std::packaged_task<int()> server_task([&]() -> int
{
routing_server->Run();
return 0;
});
auto future = server_task.get_future();
std::thread server_thread(std::move(server_task));
#ifndef _WIN32
sigset_t wait_mask;
pthread_sigmask(SIG_SETMASK, &old_mask, nullptr);
sigemptyset(&wait_mask);
sigaddset(&wait_mask, SIGINT);
sigaddset(&wait_mask, SIGQUIT);
sigaddset(&wait_mask, SIGTERM);
pthread_sigmask(SIG_BLOCK, &wait_mask, nullptr);
SimpleLogger().Write() << "running and waiting for requests";
sigwait(&wait_mask, &sig);
#else
// Set console control handler to allow server to be stopped.
console_ctrl_function = std::bind(&Server::Stop, routing_server);
SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
SimpleLogger().Write() << "running and waiting for requests";
routing_server->Run();
#endif
SimpleLogger().Write() << "initiating shutdown";
routing_server->Stop();
SimpleLogger().Write() << "stopping threads";
auto status = future.wait_for(std::chrono::seconds(2));
if (status == std::future_status::ready)
{
server_thread.join();
}
else
{
SimpleLogger().Write(logWARNING) << "Didn't exit within 2 seconds. Hard abort!";
server_task.reset(); // just kill it
}
}
SimpleLogger().Write() << "freeing objects";
routing_server.reset();
SimpleLogger().Write() << "shutdown completed";
}
catch (const std::bad_alloc &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
SimpleLogger().Write(logWARNING)
<< "Please provide more memory or consider using a larger swapfile";
return EXIT_FAILURE;
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
return EXIT_FAILURE;
}
+97
View File
@@ -0,0 +1,97 @@
/*
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 "util/version.hpp"
#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[])
{
LogPolicy::GetInstance().Unmute();
try
{
std::string ip_address;
int ip_port, requested_thread_num;
bool trial_run = false;
LibOSRMConfig lib_config;
const unsigned init_result = 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 == INIT_OK_DO_NOT_START_ENGINE)
{
return 0;
}
if (init_result == INIT_FAILED)
{
return 1;
}
SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION;
OSRM routing_machine(lib_config);
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 * COORDINATE_PRECISION,
13.438640 * COORDINATE_PRECISION);
// target_coordinate
route_parameters.coordinates.emplace_back(52.513191 * COORDINATE_PRECISION,
13.415852 * COORDINATE_PRECISION);
osrm::json::Object json_result;
const int result_code = routing_machine.RunQuery(route_parameters, json_result);
SimpleLogger().Write() << "http code: " << result_code;
osrm::json::render(SimpleLogger().Write(), json_result);
}
catch (std::exception &current_exception)
{
SimpleLogger().Write(logWARNING) << "caught exception: " << current_exception.what();
return -1;
}
return 0;
}
+102
View File
@@ -0,0 +1,102 @@
/*
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 <cstdio>
#include "../data_structures/shared_memory_factory.hpp"
#include "../server/data_structures/shared_datatype.hpp"
#include "util/version.hpp"
#include "../util/simple_logger.hpp"
void delete_region(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";
}
}();
SimpleLogger().Write(logWARNING) << "could not delete shared memory region " << name;
}
}
// find all existing shmem regions and remove them.
void springclean()
{
SimpleLogger().Write() << "spring-cleaning all shared memory regions";
delete_region(DATA_1);
delete_region(LAYOUT_1);
delete_region(DATA_2);
delete_region(LAYOUT_2);
delete_region(CURRENT_REGIONS);
}
int main()
{
LogPolicy::GetInstance().Unmute();
try
{
SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION << "\n\n";
SimpleLogger().Write() << "Releasing all locks";
SimpleLogger().Write() << "ATTENTION! BE CAREFUL!";
SimpleLogger().Write() << "----------------------";
SimpleLogger().Write() << "This tool may put osrm-routed into an undefined state!";
SimpleLogger().Write() << "Type 'Y' to acknowledge that you know what your are doing.";
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')
{
SimpleLogger().Write() << "aborted.";
return 0;
}
springclean();
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
}
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
/*
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 "util/version.hpp"
#include "../util/simple_logger.hpp"
#include "../server/data_structures/shared_barriers.hpp"
#include <iostream>
int main()
{
LogPolicy::GetInstance().Unmute();
try
{
SimpleLogger().Write() << "starting up engines, " << OSRM_VERSION;
SimpleLogger().Write() << "Releasing all locks";
SharedBarriers barrier;
barrier.pending_update_mutex.unlock();
barrier.query_mutex.unlock();
barrier.update_mutex.unlock();
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[excpetion] " << e.what();
}
return 0;
}