Merge branch 'TheMarex-ebgf-refactor' into develop
This commit is contained in:
commit
5579388896
@ -41,7 +41,7 @@ file(GLOB ExtractorGlob Extractor/*.cpp)
|
||||
set(ExtractorSources extractor.cpp ${ExtractorGlob})
|
||||
add_executable(osrm-extract ${ExtractorSources})
|
||||
|
||||
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp)
|
||||
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp)
|
||||
set(PrepareSources prepare.cpp ${PrepareGlob})
|
||||
add_executable(osrm-prepare ${PrepareSources})
|
||||
|
||||
|
145
Contractor/BFSComponentExplorer.h
Normal file
145
Contractor/BFSComponentExplorer.h
Normal file
@ -0,0 +1,145 @@
|
||||
#ifndef __BFS_COMPONENT_EXPLORER_H__
|
||||
#define __BFS_COMPONENT_EXPLORER_H__
|
||||
|
||||
#include <queue>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "../DataStructures/DynamicGraph.h"
|
||||
#include "../DataStructures/RestrictionMap.h"
|
||||
|
||||
/**
|
||||
* Explores the components of the given graph while respecting turn restrictions
|
||||
* and barriers.
|
||||
*/
|
||||
template <typename GraphT> class BFSComponentExplorer
|
||||
{
|
||||
public:
|
||||
typedef typename GraphT::NodeIterator NodeIterator;
|
||||
typedef typename GraphT::EdgeIterator EdgeIterator;
|
||||
|
||||
BFSComponentExplorer(const GraphT &dynamicGraph,
|
||||
const RestrictionMap &restrictions,
|
||||
const boost::unordered_set<NodeID> &barrier_nodes)
|
||||
: m_graph(dynamicGraph), m_restriction_map(restrictions), m_barrier_nodes(barrier_nodes)
|
||||
{
|
||||
BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the size of the component that the node belongs to.
|
||||
*/
|
||||
inline unsigned int getComponentSize(NodeID node)
|
||||
{
|
||||
BOOST_ASSERT(node < m_component_index_list.size());
|
||||
|
||||
return m_component_index_size[m_component_index_list[node]];
|
||||
}
|
||||
|
||||
inline unsigned int getNumberOfComponents() { return m_component_index_size.size(); }
|
||||
|
||||
/*!
|
||||
* Computes the component sizes.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
std::queue<std::pair<NodeID, NodeID>> bfs_queue;
|
||||
unsigned current_component = 0;
|
||||
|
||||
BOOST_ASSERT(m_component_index_list.empty());
|
||||
BOOST_ASSERT(m_component_index_size.empty());
|
||||
|
||||
unsigned num_nodes = m_graph.GetNumberOfNodes();
|
||||
|
||||
m_component_index_list.resize(num_nodes, std::numeric_limits<unsigned>::max());
|
||||
|
||||
BOOST_ASSERT(num_nodes > 0);
|
||||
|
||||
// put unexplorered node with parent pointer into queue
|
||||
for (NodeID node = 0; node < num_nodes; ++node)
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() == m_component_index_list[node])
|
||||
{
|
||||
unsigned size = exploreComponent(bfs_queue, node, current_component);
|
||||
|
||||
// push size into vector
|
||||
m_component_index_size.push_back(size);
|
||||
++current_component;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* Explores the current component that starts at node using BFS.
|
||||
*/
|
||||
inline unsigned exploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
|
||||
NodeID node,
|
||||
unsigned current_component)
|
||||
{
|
||||
bfs_queue.push(std::make_pair(node, node));
|
||||
// mark node as read
|
||||
m_component_index_list[node] = current_component;
|
||||
|
||||
unsigned current_component_size = 1;
|
||||
|
||||
while (!bfs_queue.empty())
|
||||
{
|
||||
// fetch element from BFS queue
|
||||
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
|
||||
bfs_queue.pop();
|
||||
|
||||
const NodeID v = current_queue_item.first; // current node
|
||||
const NodeID u = current_queue_item.second; // parent
|
||||
// increment size counter of current component
|
||||
++current_component_size;
|
||||
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
|
||||
if (!is_barrier_node)
|
||||
{
|
||||
const NodeID to_node_of_only_restriction =
|
||||
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
|
||||
|
||||
for (EdgeIterator e2 = m_graph.BeginEdges(v); e2 < m_graph.EndEdges(v); ++e2)
|
||||
{
|
||||
NodeIterator w = m_graph.GetTarget(e2);
|
||||
|
||||
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
|
||||
w != to_node_of_only_restriction)
|
||||
{
|
||||
// At an only_-restriction but not at the right turn
|
||||
continue;
|
||||
}
|
||||
|
||||
if (u != w)
|
||||
{
|
||||
// only add an edge if turn is not a U-turn except
|
||||
// when it is at the end of a dead-end street.
|
||||
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
|
||||
{
|
||||
// only add an edge if turn is not prohibited
|
||||
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
|
||||
{
|
||||
// insert next (node, parent) only if w has
|
||||
// not yet been explored
|
||||
// mark node as read
|
||||
m_component_index_list[w] = current_component;
|
||||
bfs_queue.push(std::make_pair(w, v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return current_component_size;
|
||||
}
|
||||
|
||||
std::vector<unsigned> m_component_index_list;
|
||||
std::vector<NodeID> m_component_index_size;
|
||||
|
||||
const GraphT &m_graph;
|
||||
const RestrictionMap &m_restriction_map;
|
||||
const boost::unordered_set<NodeID> &m_barrier_nodes;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -35,20 +35,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "../DataStructures/DynamicGraph.h"
|
||||
#include "../DataStructures/EdgeBasedNode.h"
|
||||
#include "../DataStructures/HashTable.h"
|
||||
#include "../DataStructures/ImportEdge.h"
|
||||
#include "../DataStructures/OriginalEdgeData.h"
|
||||
#include "../DataStructures/Percent.h"
|
||||
#include "../DataStructures/QueryEdge.h"
|
||||
#include "../DataStructures/QueryNode.h"
|
||||
#include "../DataStructures/TurnInstructions.h"
|
||||
#include "../DataStructures/Restriction.h"
|
||||
#include "../DataStructures/NodeBasedGraph.h"
|
||||
#include "../DataStructures/RestrictionMap.h"
|
||||
#include "../Util/LuaUtil.h"
|
||||
#include "../Util/SimpleLogger.h"
|
||||
|
||||
#include "GeometryCompressor.h"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
@ -57,155 +57,76 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
class EdgeBasedGraphFactory : boost::noncopyable {
|
||||
public:
|
||||
class EdgeBasedGraphFactory : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
struct SpeedProfileProperties;
|
||||
|
||||
explicit EdgeBasedGraphFactory(
|
||||
int number_of_nodes,
|
||||
std::vector<ImportEdge> & input_edge_list,
|
||||
std::vector<NodeID> & barrier_node_list,
|
||||
std::vector<NodeID> & traffic_light_node_list,
|
||||
std::vector<TurnRestriction> & input_restrictions_list,
|
||||
std::vector<NodeInfo> & m_node_info_list,
|
||||
SpeedProfileProperties & speed_profile
|
||||
);
|
||||
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
||||
std::unique_ptr<RestrictionMap> restricion_map,
|
||||
std::vector<NodeID> &barrier_node_list,
|
||||
std::vector<NodeID> &traffic_light_node_list,
|
||||
std::vector<NodeInfo> &m_node_info_list,
|
||||
SpeedProfileProperties &speed_profile);
|
||||
|
||||
void Run(
|
||||
const std::string & original_edge_data_filename,
|
||||
const std::string & geometry_filename,
|
||||
lua_State *myLuaState
|
||||
);
|
||||
void Run(const std::string &original_edge_data_filename,
|
||||
const std::string &geometry_filename,
|
||||
lua_State *myLuaState);
|
||||
|
||||
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
||||
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
|
||||
|
||||
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
|
||||
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
|
||||
|
||||
TurnInstruction AnalyzeTurn(
|
||||
const NodeID u,
|
||||
const NodeID v,
|
||||
const NodeID w
|
||||
) const;
|
||||
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
|
||||
|
||||
int GetTurnPenalty(
|
||||
const NodeID u,
|
||||
const NodeID v,
|
||||
const NodeID w,
|
||||
lua_State *myLuaState
|
||||
) const;
|
||||
int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const;
|
||||
|
||||
unsigned GetNumberOfEdgeBasedNodes() const;
|
||||
|
||||
struct SpeedProfileProperties{
|
||||
SpeedProfileProperties() :
|
||||
trafficSignalPenalty(0),
|
||||
uTurnPenalty(0),
|
||||
has_turn_penalty_function(false)
|
||||
{ }
|
||||
struct SpeedProfileProperties
|
||||
{
|
||||
SpeedProfileProperties()
|
||||
: trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false)
|
||||
{
|
||||
}
|
||||
|
||||
int trafficSignalPenalty;
|
||||
int uTurnPenalty;
|
||||
bool has_turn_penalty_function;
|
||||
} speed_profile;
|
||||
|
||||
private:
|
||||
struct NodeBasedEdgeData {
|
||||
NodeBasedEdgeData() : distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID), nameID(std::numeric_limits<unsigned>::max()),
|
||||
type(std::numeric_limits<short>::max()), isAccessRestricted(false), shortcut(false), forward(false), backward(false),
|
||||
roundabout(false), ignore_in_grid(false), contraFlow(false)
|
||||
{ }
|
||||
|
||||
int distance;
|
||||
unsigned edgeBasedNodeID;
|
||||
unsigned nameID;
|
||||
short type;
|
||||
bool isAccessRestricted:1;
|
||||
bool shortcut:1;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
bool roundabout:1;
|
||||
bool ignore_in_grid:1;
|
||||
bool contraFlow:1;
|
||||
|
||||
void SwapDirectionFlags() {
|
||||
bool temp_flag = forward;
|
||||
forward = backward;
|
||||
backward = temp_flag;
|
||||
}
|
||||
|
||||
bool IsEqualTo( const NodeBasedEdgeData & other ) const {
|
||||
return (forward == other.forward) &&
|
||||
(backward == other.backward) &&
|
||||
(nameID == other.nameID) &&
|
||||
(ignore_in_grid == other.ignore_in_grid) &&
|
||||
(contraFlow == other.contraFlow);
|
||||
}
|
||||
};
|
||||
|
||||
unsigned m_turn_restrictions_count;
|
||||
unsigned m_number_of_edge_based_nodes;
|
||||
|
||||
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
|
||||
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
|
||||
private:
|
||||
typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
|
||||
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
|
||||
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
|
||||
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
||||
typedef std::pair<NodeID, bool> RestrictionTarget;
|
||||
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
|
||||
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
|
||||
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
|
||||
|
||||
std::vector<NodeInfo> m_node_info_list;
|
||||
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
||||
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
unsigned m_number_of_edge_based_nodes;
|
||||
|
||||
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
||||
boost::unordered_set<NodeID> m_barrier_nodes;
|
||||
boost::unordered_set<NodeID> m_traffic_lights;
|
||||
std::vector<NodeInfo> m_node_info_list;
|
||||
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
||||
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||
|
||||
RestrictionMap m_restriction_map;
|
||||
GeometryCompressor m_geometry_compressor;
|
||||
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
||||
boost::unordered_set<NodeID> m_barrier_nodes;
|
||||
boost::unordered_set<NodeID> m_traffic_lights;
|
||||
|
||||
NodeID CheckForEmanatingIsOnlyTurn(
|
||||
const NodeID u,
|
||||
const NodeID v
|
||||
) const;
|
||||
std::unique_ptr<RestrictionMap> m_restriction_map;
|
||||
|
||||
bool CheckIfTurnIsRestricted(
|
||||
const NodeID u,
|
||||
const NodeID v,
|
||||
const NodeID w
|
||||
) const;
|
||||
GeometryCompressor m_geometry_compressor;
|
||||
|
||||
void InsertEdgeBasedNode(
|
||||
NodeBasedDynamicGraph::NodeIterator u,
|
||||
NodeBasedDynamicGraph::NodeIterator v,
|
||||
NodeBasedDynamicGraph::EdgeIterator e1,
|
||||
bool belongsToTinyComponent
|
||||
);
|
||||
void CompressGeometry();
|
||||
void RenumberEdges();
|
||||
void GenerateEdgeExpandedNodes();
|
||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
||||
lua_State *lua_state);
|
||||
|
||||
void BFSCompentExplorer(
|
||||
std::vector<unsigned> & component_index_list,
|
||||
std::vector<unsigned> & component_index_size
|
||||
) const;
|
||||
void InsertEdgeBasedNode(NodeBasedDynamicGraph::NodeIterator u,
|
||||
NodeBasedDynamicGraph::NodeIterator v,
|
||||
NodeBasedDynamicGraph::EdgeIterator e1,
|
||||
bool belongsToTinyComponent);
|
||||
|
||||
void FlushVectorToStream(
|
||||
std::ofstream & edge_data_file,
|
||||
std::vector<OriginalEdgeData> & original_edge_data_vector
|
||||
) const;
|
||||
|
||||
void FixupArrivingTurnRestriction(
|
||||
const NodeID u,
|
||||
const NodeID v,
|
||||
const NodeID w
|
||||
);
|
||||
|
||||
void FixupStartingTurnRestriction(
|
||||
const NodeID u,
|
||||
const NodeID v,
|
||||
const NodeID w
|
||||
);
|
||||
void FlushVectorToStream(std::ofstream &edge_data_file,
|
||||
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
|
||||
|
||||
unsigned max_id;
|
||||
};
|
||||
|
@ -70,18 +70,18 @@ unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
|
||||
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
|
||||
{
|
||||
|
||||
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary|std::ios::out);
|
||||
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
|
||||
const unsigned number_of_compressed_geometries = m_compressed_geometries.size() + 1;
|
||||
BOOST_ASSERT(UINT_MAX != number_of_compressed_geometries);
|
||||
geometry_out_stream.write((char *)&number_of_compressed_geometries, sizeof(unsigned));
|
||||
|
||||
// write indices array
|
||||
unsigned prefix_sum_of_list_indices = 0;
|
||||
for (unsigned i = 0; i < m_compressed_geometries.size(); ++i)
|
||||
for (auto &elem : m_compressed_geometries)
|
||||
{
|
||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
||||
|
||||
const std::vector<CompressedNode> ¤t_vector = m_compressed_geometries.at(i);
|
||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
||||
const unsigned unpacked_size = current_vector.size();
|
||||
BOOST_ASSERT(UINT_MAX != unpacked_size);
|
||||
prefix_sum_of_list_indices += unpacked_size;
|
||||
@ -94,9 +94,9 @@ void GeometryCompressor::SerializeInternalVector(const std::string &path) const
|
||||
|
||||
unsigned control_sum = 0;
|
||||
// write compressed geometries
|
||||
for (unsigned i = 0; i < m_compressed_geometries.size(); ++i)
|
||||
for (auto &elem : m_compressed_geometries)
|
||||
{
|
||||
const std::vector<CompressedNode> ¤t_vector = m_compressed_geometries[i];
|
||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
||||
const unsigned unpacked_size = current_vector.size();
|
||||
control_sum += unpacked_size;
|
||||
BOOST_ASSERT(UINT_MAX != unpacked_size);
|
||||
@ -122,8 +122,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
||||
BOOST_ASSERT(std::numeric_limits<int>::max() != weight1);
|
||||
BOOST_ASSERT(std::numeric_limits<int>::max() != weight2);
|
||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
|
||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
|
||||
|
||||
// append list of removed edge_id plus via node to surviving edge id:
|
||||
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
|
||||
@ -146,7 +146,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
|
||||
m_free_list.pop_back();
|
||||
}
|
||||
|
||||
const boost::unordered_map<EdgeID, unsigned>::const_iterator iter = m_edge_id_to_list_index_map.find(edge_id_1);
|
||||
const boost::unordered_map<EdgeID, unsigned>::const_iterator iter =
|
||||
m_edge_id_to_list_index_map.find(edge_id_1);
|
||||
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
|
||||
const unsigned edge_bucket_id1 = iter->second;
|
||||
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));
|
||||
|
@ -56,7 +56,7 @@ class GeometryCompressor
|
||||
|
||||
private:
|
||||
void IncreaseFreeList();
|
||||
std::vector<std::vector<CompressedNode> > m_compressed_geometries;
|
||||
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
|
||||
std::vector<unsigned> m_free_list;
|
||||
boost::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
|
||||
};
|
||||
|
@ -27,136 +27,154 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "TemporaryStorage.h"
|
||||
|
||||
TemporaryStorage::TemporaryStorage() {
|
||||
temp_directory = boost::filesystem::temp_directory_path();
|
||||
}
|
||||
TemporaryStorage::TemporaryStorage() { temp_directory = boost::filesystem::temp_directory_path(); }
|
||||
|
||||
TemporaryStorage & TemporaryStorage::GetInstance(){
|
||||
TemporaryStorage &TemporaryStorage::GetInstance()
|
||||
{
|
||||
static TemporaryStorage static_instance;
|
||||
return static_instance;
|
||||
}
|
||||
|
||||
TemporaryStorage::~TemporaryStorage() {
|
||||
RemoveAll();
|
||||
}
|
||||
TemporaryStorage::~TemporaryStorage() { RemoveAll(); }
|
||||
|
||||
void TemporaryStorage::RemoveAll() {
|
||||
void TemporaryStorage::RemoveAll()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
for(unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id) {
|
||||
for (unsigned slot_id = 0; slot_id < stream_data_list.size(); ++slot_id)
|
||||
{
|
||||
DeallocateSlot(slot_id);
|
||||
}
|
||||
stream_data_list.clear();
|
||||
}
|
||||
|
||||
int TemporaryStorage::AllocateSlot() {
|
||||
int TemporaryStorage::AllocateSlot()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
try {
|
||||
try
|
||||
{
|
||||
stream_data_list.push_back(StreamData());
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
CheckIfTemporaryDeviceFull();
|
||||
return stream_data_list.size() - 1;
|
||||
}
|
||||
|
||||
void TemporaryStorage::DeallocateSlot(const int slot_id) {
|
||||
try {
|
||||
StreamData & data = stream_data_list[slot_id];
|
||||
void TemporaryStorage::DeallocateSlot(const int slot_id)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamData &data = stream_data_list[slot_id];
|
||||
boost::mutex::scoped_lock lock(*data.readWriteMutex);
|
||||
if(!boost::filesystem::exists(data.temp_path)) {
|
||||
if (!boost::filesystem::exists(data.temp_path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(data.temp_file->is_open()) {
|
||||
if (data.temp_file->is_open())
|
||||
{
|
||||
data.temp_file->close();
|
||||
}
|
||||
|
||||
boost::filesystem::remove(data.temp_path);
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
}
|
||||
|
||||
void TemporaryStorage::WriteToSlot(
|
||||
const int slot_id,
|
||||
char * pointer,
|
||||
const std::size_t size
|
||||
) {
|
||||
try {
|
||||
StreamData & data = stream_data_list[slot_id];
|
||||
void TemporaryStorage::WriteToSlot(const int slot_id, char *pointer, const std::size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamData &data = stream_data_list[slot_id];
|
||||
BOOST_ASSERT(data.write_mode);
|
||||
|
||||
boost::mutex::scoped_lock lock(*data.readWriteMutex);
|
||||
BOOST_ASSERT_MSG(
|
||||
data.write_mode,
|
||||
"Writing after first read is not allowed"
|
||||
);
|
||||
if( 1073741824 < data.buffer.size() ) {
|
||||
BOOST_ASSERT_MSG(data.write_mode, "Writing after first read is not allowed");
|
||||
if (1073741824 < data.buffer.size())
|
||||
{
|
||||
data.temp_file->write(&data.buffer[0], data.buffer.size());
|
||||
// data.temp_file->write(pointer, size);
|
||||
data.buffer.clear();
|
||||
CheckIfTemporaryDeviceFull();
|
||||
}
|
||||
data.buffer.insert(data.buffer.end(), pointer, pointer+size);
|
||||
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
data.buffer.insert(data.buffer.end(), pointer, pointer + size);
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
}
|
||||
void TemporaryStorage::ReadFromSlot(
|
||||
const int slot_id,
|
||||
char * pointer,
|
||||
const std::size_t size
|
||||
) {
|
||||
try {
|
||||
StreamData & data = stream_data_list[slot_id];
|
||||
void TemporaryStorage::ReadFromSlot(const int slot_id, char *pointer, const std::size_t size)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamData &data = stream_data_list[slot_id];
|
||||
boost::mutex::scoped_lock lock(*data.readWriteMutex);
|
||||
if( data.write_mode ) {
|
||||
if (data.write_mode)
|
||||
{
|
||||
data.write_mode = false;
|
||||
data.temp_file->write(&data.buffer[0], data.buffer.size());
|
||||
data.buffer.clear();
|
||||
data.temp_file->seekg( data.temp_file->beg );
|
||||
BOOST_ASSERT( data.temp_file->beg == data.temp_file->tellg() );
|
||||
data.temp_file->seekg(data.temp_file->beg);
|
||||
BOOST_ASSERT(data.temp_file->beg == data.temp_file->tellg());
|
||||
}
|
||||
BOOST_ASSERT( !data.write_mode );
|
||||
BOOST_ASSERT(!data.write_mode);
|
||||
data.temp_file->read(pointer, size);
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice() {
|
||||
uint64_t TemporaryStorage::GetFreeBytesOnTemporaryDevice()
|
||||
{
|
||||
uint64_t value = -1;
|
||||
try {
|
||||
boost::filesystem::path p = boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::space_info s = boost::filesystem::space( p );
|
||||
try
|
||||
{
|
||||
boost::filesystem::path p = boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::space_info s = boost::filesystem::space(p);
|
||||
value = s.free;
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void TemporaryStorage::CheckIfTemporaryDeviceFull() {
|
||||
void TemporaryStorage::CheckIfTemporaryDeviceFull()
|
||||
{
|
||||
boost::filesystem::path p = boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::space_info s = boost::filesystem::space( p );
|
||||
if( (1024*1024) > s.free ) {
|
||||
boost::filesystem::space_info s = boost::filesystem::space(p);
|
||||
if ((1024 * 1024) > s.free)
|
||||
{
|
||||
throw OSRMException("temporary device is full");
|
||||
}
|
||||
}
|
||||
|
||||
boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id) {
|
||||
boost::filesystem::fstream::pos_type TemporaryStorage::Tell(const int slot_id)
|
||||
{
|
||||
boost::filesystem::fstream::pos_type position;
|
||||
try {
|
||||
StreamData & data = stream_data_list[slot_id];
|
||||
try
|
||||
{
|
||||
StreamData &data = stream_data_list[slot_id];
|
||||
boost::mutex::scoped_lock lock(*data.readWriteMutex);
|
||||
position = data.temp_file->tellp();
|
||||
} catch(boost::filesystem::filesystem_error & e) {
|
||||
}
|
||||
catch (boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
Abort(e);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error& e) {
|
||||
void TemporaryStorage::Abort(const boost::filesystem::filesystem_error &e)
|
||||
{
|
||||
RemoveAll();
|
||||
throw OSRMException(e.what());
|
||||
}
|
||||
|
@ -36,8 +36,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
@ -56,61 +54,52 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
static boost::filesystem::path temp_directory;
|
||||
static std::string TemporaryFilePattern("OSRM-%%%%-%%%%-%%%%");
|
||||
class TemporaryStorage {
|
||||
public:
|
||||
static TemporaryStorage & GetInstance();
|
||||
class TemporaryStorage
|
||||
{
|
||||
public:
|
||||
static TemporaryStorage &GetInstance();
|
||||
virtual ~TemporaryStorage();
|
||||
|
||||
int AllocateSlot();
|
||||
void DeallocateSlot(const int slot_id);
|
||||
void WriteToSlot(const int slot_id, char * pointer, const std::size_t size);
|
||||
void ReadFromSlot(const int slot_id, char * pointer, const std::size_t size);
|
||||
//returns the number of free bytes
|
||||
void WriteToSlot(const int slot_id, char *pointer, const std::size_t size);
|
||||
void ReadFromSlot(const int slot_id, char *pointer, const std::size_t size);
|
||||
// returns the number of free bytes
|
||||
uint64_t GetFreeBytesOnTemporaryDevice();
|
||||
boost::filesystem::fstream::pos_type Tell(const int slot_id);
|
||||
void RemoveAll();
|
||||
private:
|
||||
|
||||
private:
|
||||
TemporaryStorage();
|
||||
TemporaryStorage(TemporaryStorage const &){};
|
||||
TemporaryStorage(TemporaryStorage const &) {};
|
||||
|
||||
TemporaryStorage & operator=(TemporaryStorage const &) {
|
||||
return *this;
|
||||
}
|
||||
TemporaryStorage &operator=(TemporaryStorage const &) { return *this; }
|
||||
|
||||
void Abort(const boost::filesystem::filesystem_error& e);
|
||||
void Abort(const boost::filesystem::filesystem_error &e);
|
||||
void CheckIfTemporaryDeviceFull();
|
||||
|
||||
struct StreamData {
|
||||
struct StreamData
|
||||
{
|
||||
bool write_mode;
|
||||
boost::filesystem::path temp_path;
|
||||
boost::shared_ptr<boost::filesystem::fstream> temp_file;
|
||||
boost::shared_ptr<boost::mutex> readWriteMutex;
|
||||
std::shared_ptr<boost::filesystem::fstream> temp_file;
|
||||
std::shared_ptr<boost::mutex> readWriteMutex;
|
||||
std::vector<char> buffer;
|
||||
|
||||
StreamData() :
|
||||
write_mode(true),
|
||||
temp_path(
|
||||
boost::filesystem::unique_path(
|
||||
temp_directory.append(
|
||||
TemporaryFilePattern.begin(),
|
||||
TemporaryFilePattern.end()
|
||||
)
|
||||
)
|
||||
),
|
||||
temp_file(
|
||||
new boost::filesystem::fstream(
|
||||
temp_path,
|
||||
std::ios::in|std::ios::out|std::ios::trunc|std::ios::binary
|
||||
)
|
||||
),
|
||||
readWriteMutex(boost::make_shared<boost::mutex>())
|
||||
StreamData()
|
||||
: write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append(
|
||||
TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
|
||||
temp_file(new boost::filesystem::fstream(
|
||||
temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
|
||||
readWriteMutex(std::make_shared<boost::mutex>())
|
||||
{
|
||||
if( temp_file->fail() ) {
|
||||
if (temp_file->fail())
|
||||
{
|
||||
throw OSRMException("temporary file could not be created");
|
||||
}
|
||||
}
|
||||
};
|
||||
//vector of file streams that is used to store temporary data
|
||||
// vector of file streams that is used to store temporary data
|
||||
boost::mutex mutex;
|
||||
std::vector<StreamData> stream_data_list;
|
||||
};
|
||||
|
110
DataStructures/NodeBasedGraph.h
Normal file
110
DataStructures/NodeBasedGraph.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef __NODE_BASED_GRAPH_H__
|
||||
#define __NODE_BASED_GRAPH_H__
|
||||
|
||||
#include "DynamicGraph.h"
|
||||
#include "ImportEdge.h"
|
||||
|
||||
struct NodeBasedEdgeData
|
||||
{
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
|
||||
nameID(std::numeric_limits<unsigned>::max()), type(std::numeric_limits<short>::max()),
|
||||
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
|
||||
roundabout(false), ignore_in_grid(false), contraFlow(false)
|
||||
{
|
||||
}
|
||||
|
||||
int distance;
|
||||
unsigned edgeBasedNodeID;
|
||||
unsigned nameID;
|
||||
short type;
|
||||
bool isAccessRestricted : 1;
|
||||
bool shortcut : 1;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
bool roundabout : 1;
|
||||
bool ignore_in_grid : 1;
|
||||
bool contraFlow : 1;
|
||||
|
||||
void SwapDirectionFlags()
|
||||
{
|
||||
bool temp_flag = forward;
|
||||
forward = backward;
|
||||
backward = temp_flag;
|
||||
}
|
||||
|
||||
bool IsEqualTo(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (forward == other.forward) && (backward == other.backward) &&
|
||||
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
|
||||
(contraFlow == other.contraFlow);
|
||||
}
|
||||
};
|
||||
|
||||
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
|
||||
|
||||
// Factory method to create NodeBasedDynamicGraph from ImportEdges
|
||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
||||
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
|
||||
{
|
||||
typedef NodeBasedDynamicGraph::InputEdge DynInputEdge;
|
||||
|
||||
std::sort(input_edge_list.begin(), input_edge_list.end());
|
||||
|
||||
// TODO: remove duplicate edges
|
||||
DeallocatingVector<DynInputEdge> edges_list;
|
||||
DynInputEdge edge;
|
||||
for (const ImportEdge &import_edge : input_edge_list)
|
||||
{
|
||||
|
||||
if (!import_edge.isForward())
|
||||
{
|
||||
edge.source = import_edge.target();
|
||||
edge.target = import_edge.source();
|
||||
edge.data.backward = import_edge.isForward();
|
||||
edge.data.forward = import_edge.isBackward();
|
||||
}
|
||||
else
|
||||
{
|
||||
edge.source = import_edge.source();
|
||||
edge.target = import_edge.target();
|
||||
edge.data.forward = import_edge.isForward();
|
||||
edge.data.backward = import_edge.isBackward();
|
||||
}
|
||||
|
||||
if (edge.source == edge.target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
edge.data.distance = (std::max)((int)import_edge.weight(), 1);
|
||||
BOOST_ASSERT(edge.data.distance > 0);
|
||||
edge.data.shortcut = false;
|
||||
edge.data.roundabout = import_edge.isRoundabout();
|
||||
edge.data.ignore_in_grid = import_edge.ignoreInGrid();
|
||||
edge.data.nameID = import_edge.name();
|
||||
edge.data.type = import_edge.type();
|
||||
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
|
||||
edge.data.contraFlow = import_edge.isContraFlow();
|
||||
edges_list.push_back(edge);
|
||||
|
||||
if (!import_edge.IsSplit())
|
||||
{
|
||||
using std::swap; // enable ADL
|
||||
swap(edge.source, edge.target);
|
||||
edge.data.SwapDirectionFlags();
|
||||
edges_list.push_back(edge);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(edges_list.begin(), edges_list.end());
|
||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(number_of_nodes, edges_list);
|
||||
|
||||
// FIXME probably unneeded since this is the end of scope
|
||||
DeallocatingVector<DynInputEdge>().swap(edges_list);
|
||||
BOOST_ASSERT(0 == edges_list.size());
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
#endif
|
168
DataStructures/RestrictionMap.cpp
Normal file
168
DataStructures/RestrictionMap.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
#include "RestrictionMap.h"
|
||||
#include "NodeBasedGraph.h"
|
||||
|
||||
RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
|
||||
const std::vector<TurnRestriction> &input_restrictions_list)
|
||||
: m_count(0), m_graph(graph)
|
||||
{
|
||||
// decompose restirction consisting of a start, via and end note into a start-edge
|
||||
// and all end-nodes
|
||||
for (auto &restriction : input_restrictions_list)
|
||||
{
|
||||
std::pair<NodeID, NodeID> restriction_source =
|
||||
std::make_pair(restriction.fromNode, restriction.viaNode);
|
||||
unsigned index;
|
||||
auto restriction_iter = m_restriction_map.find(restriction_source);
|
||||
if (restriction_iter == m_restriction_map.end())
|
||||
{
|
||||
index = m_restriction_bucket_list.size();
|
||||
m_restriction_bucket_list.resize(index + 1);
|
||||
m_restriction_map.emplace(restriction_source, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = restriction_iter->second;
|
||||
// Map already contains an is_only_*-restriction
|
||||
if (m_restriction_bucket_list.at(index).begin()->second)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (restriction.flags.isOnly)
|
||||
{
|
||||
// We are going to insert an is_only_*-restriction. There can be only one.
|
||||
m_count -= m_restriction_bucket_list.at(index).size();
|
||||
m_restriction_bucket_list.at(index).clear();
|
||||
}
|
||||
}
|
||||
++m_count;
|
||||
m_restriction_bucket_list.at(index)
|
||||
.push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace end v with w in each turn restriction containing u as via node
|
||||
*
|
||||
* Note: We need access to node based graph.
|
||||
*/
|
||||
void RestrictionMap::FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w)
|
||||
{
|
||||
BOOST_ASSERT(u != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(v != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(w != std::numeric_limits<unsigned>::max());
|
||||
|
||||
// find all possible start edges
|
||||
// it is more efficent to get a (small) list of potential start edges
|
||||
// than iterating over all buckets
|
||||
std::vector<NodeID> predecessors;
|
||||
for (EdgeID current_edge_id = m_graph->BeginEdges(u); current_edge_id < m_graph->EndEdges(u);
|
||||
++current_edge_id)
|
||||
{
|
||||
const EdgeData &edge_data = m_graph->GetEdgeData(current_edge_id);
|
||||
const NodeID target = m_graph->GetTarget(current_edge_id);
|
||||
if (edge_data.backward && (v != target))
|
||||
{
|
||||
predecessors.push_back(target);
|
||||
}
|
||||
}
|
||||
|
||||
for (const NodeID x : predecessors)
|
||||
{
|
||||
const std::pair<NodeID, NodeID> restr_start = std::make_pair(x, u);
|
||||
auto restriction_iterator = m_restriction_map.find(restr_start);
|
||||
if (restriction_iterator == m_restriction_map.end())
|
||||
continue;
|
||||
|
||||
const unsigned index = restriction_iterator->second;
|
||||
auto &bucket = m_restriction_bucket_list.at(index);
|
||||
for (RestrictionTarget &restriction_target : bucket)
|
||||
{
|
||||
if (v == restriction_target.first)
|
||||
{
|
||||
restriction_target.first = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the start edge (v, w) with (u, w), only start node changes.
|
||||
*/
|
||||
void RestrictionMap::FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w)
|
||||
{
|
||||
BOOST_ASSERT(u != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(v != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(w != std::numeric_limits<unsigned>::max());
|
||||
|
||||
const std::pair<NodeID, NodeID> old_start = std::make_pair(v, w);
|
||||
|
||||
auto restriction_iterator = m_restriction_map.find(old_start);
|
||||
if (restriction_iterator != m_restriction_map.end())
|
||||
{
|
||||
const unsigned index = restriction_iterator->second;
|
||||
// remove old restriction start (v,w)
|
||||
m_restriction_map.erase(restriction_iterator);
|
||||
|
||||
// insert new restriction start (u,w) (point to index)
|
||||
const std::pair<NodeID, NodeID> new_start = std::make_pair(u, w);
|
||||
m_restriction_map.insert(std::make_pair(new_start, index));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the edge (u, v) is contained in any turn restriction.
|
||||
* If so returns id of first target node.
|
||||
*/
|
||||
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
|
||||
{
|
||||
BOOST_ASSERT(u != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(v != std::numeric_limits<unsigned>::max());
|
||||
|
||||
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
|
||||
auto restriction_iter = m_restriction_map.find(restriction_source);
|
||||
|
||||
if (restriction_iter != m_restriction_map.end())
|
||||
{
|
||||
const unsigned index = restriction_iter->second;
|
||||
auto &bucket = m_restriction_bucket_list.at(index);
|
||||
for (const RestrictionSource &restriction_target : bucket)
|
||||
{
|
||||
if (restriction_target.second)
|
||||
{
|
||||
return restriction_target.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the turn described by start u, via v and targed w is covert by any turn restriction.
|
||||
*/
|
||||
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
|
||||
{
|
||||
BOOST_ASSERT(u != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(v != std::numeric_limits<unsigned>::max());
|
||||
BOOST_ASSERT(w != std::numeric_limits<unsigned>::max());
|
||||
|
||||
const std::pair<NodeID, NodeID> restriction_source = std::make_pair(u, v);
|
||||
auto restriction_iter = m_restriction_map.find(restriction_source);
|
||||
|
||||
if (restriction_iter != m_restriction_map.end())
|
||||
{
|
||||
const unsigned index = restriction_iter->second;
|
||||
auto &bucket = m_restriction_bucket_list.at(index);
|
||||
for (const RestrictionTarget &restriction_target : bucket)
|
||||
{
|
||||
if ((w == restriction_target.first) && // target found
|
||||
(!restriction_target.second) // and not an only_-restr.
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
71
DataStructures/RestrictionMap.h
Normal file
71
DataStructures/RestrictionMap.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __RESTRICTION_MAP_H__
|
||||
#define __RESTRICTION_MAP_H__
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "DynamicGraph.h"
|
||||
#include "Restriction.h"
|
||||
#include "NodeBasedGraph.h"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
/*!
|
||||
* Makee it efficent to look up if an edge is the start + via node of a TurnRestriction.
|
||||
* Is needed by EdgeBasedGraphFactory.
|
||||
*/
|
||||
class RestrictionMap
|
||||
{
|
||||
public:
|
||||
RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
|
||||
const std::vector<TurnRestriction> &input_restrictions_list);
|
||||
|
||||
void FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
|
||||
void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
|
||||
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
|
||||
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
|
||||
|
||||
unsigned size() { return m_count; }
|
||||
|
||||
private:
|
||||
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
||||
typedef std::pair<NodeID, bool> RestrictionTarget;
|
||||
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
|
||||
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
|
||||
|
||||
unsigned m_count;
|
||||
std::shared_ptr<NodeBasedDynamicGraph> m_graph;
|
||||
//! index -> list of (target, isOnly)
|
||||
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||
//! maps (start, via) -> bucket index
|
||||
boost::unordered_map<RestrictionSource, unsigned> m_restriction_map;
|
||||
};
|
||||
|
||||
#endif
|
58
Util/TimingUtil.h
Normal file
58
Util/TimingUtil.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TIMINGUTIL_H_
|
||||
#define TIMINGUTIL_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <winsock.h>
|
||||
void gettimeofday(struct timeval* t,void* timezone) {
|
||||
struct _timeb timebuffer;
|
||||
_ftime( &timebuffer );
|
||||
t->tv_sec=timebuffer.time;
|
||||
t->tv_usec=1000*timebuffer.millitm;
|
||||
}
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
|
||||
static inline double get_timestamp() {
|
||||
struct timeval tp;
|
||||
gettimeofday(&tp, NULL);
|
||||
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
|
||||
}
|
||||
|
||||
#define TIMER_START(_X) timeval _X##_start, _X##_stop; gettimeofday(&_X##_start, NULL)
|
||||
#define TIMER_STOP(_X) gettimeofday(&_X##_stop, NULL);
|
||||
#define TIMER_MSEC(_X) ((_X##_stop.tv_sec - _X##_start.tv_sec) * 1000.0 + (_X##_stop.tv_usec - _X##_start.tv_usec) / 1000.0)
|
||||
#define TIMER_SEC(_X) ((_X##_stop.tv_sec - _X##_start.tv_sec) + (_X##_stop.tv_usec - _X##_start.tv_usec) / 1000.0 / 1000.0)
|
||||
#define TIMER_MIN(_X) ((_X##_stop.tv_sec - _X##_start.tv_sec) / 60.0)
|
||||
|
||||
#endif /* TIMINGUTIL_H_ */
|
14
prepare.cpp
14
prepare.cpp
@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "DataStructures/QueryEdge.h"
|
||||
#include "DataStructures/StaticGraph.h"
|
||||
#include "DataStructures/StaticRTree.h"
|
||||
#include "DataStructures/RestrictionMap.h"
|
||||
#include "Util/GitDescription.h"
|
||||
#include "Util/GraphLoader.h"
|
||||
#include "Util/LuaUtil.h"
|
||||
@ -48,7 +49,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <luabind/luabind.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -274,12 +274,13 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
|
||||
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
||||
EdgeBasedGraphFactory *edge_based_graph_factor =
|
||||
new EdgeBasedGraphFactory(number_of_node_based_nodes,
|
||||
edge_list,
|
||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph = NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
||||
std::unique_ptr<RestrictionMap> restriction_map = std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list));
|
||||
EdgeBasedGraphFactory * edge_based_graph_factor =
|
||||
new EdgeBasedGraphFactory(node_based_graph,
|
||||
std::move(restriction_map),
|
||||
barrier_node_list,
|
||||
traffic_light_list,
|
||||
restriction_list,
|
||||
internal_to_external_node_map,
|
||||
speed_profile);
|
||||
edge_list.clear();
|
||||
@ -302,6 +303,9 @@ int main(int argc, char *argv[])
|
||||
edge_based_graph_factor->GetEdgeBasedNodes(node_based_edge_list);
|
||||
delete edge_based_graph_factor;
|
||||
|
||||
// TODO actually use scoping: Split this up in subfunctions
|
||||
node_based_graph.reset();
|
||||
|
||||
std::chrono::duration<double> end_of_expansion_time =
|
||||
std::chrono::steady_clock::now() - startup_time;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user