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; | ||||
| 
 | ||||
|     unsigned m_number_of_edge_based_nodes; | ||||
| 
 | ||||
|     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; | ||||
| 
 | ||||
|     boost::shared_ptr<NodeBasedDynamicGraph>    m_node_based_graph; | ||||
|     std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph; | ||||
|     boost::unordered_set<NodeID> m_barrier_nodes; | ||||
|     boost::unordered_set<NodeID> m_traffic_lights; | ||||
| 
 | ||||
|     RestrictionMap                              m_restriction_map; | ||||
|     std::unique_ptr<RestrictionMap> m_restriction_map; | ||||
| 
 | ||||
|     GeometryCompressor m_geometry_compressor; | ||||
| 
 | ||||
|     NodeID CheckForEmanatingIsOnlyTurn( | ||||
|         const NodeID u, | ||||
|         const NodeID v | ||||
|     ) const; | ||||
|     void CompressGeometry(); | ||||
|     void RenumberEdges(); | ||||
|     void GenerateEdgeExpandedNodes(); | ||||
|     void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename, | ||||
|                                    lua_State *lua_state); | ||||
| 
 | ||||
|     bool CheckIfTurnIsRestricted( | ||||
|         const NodeID u, | ||||
|         const NodeID v, | ||||
|         const NodeID w | ||||
|     ) const; | ||||
| 
 | ||||
|     void InsertEdgeBasedNode( | ||||
|         NodeBasedDynamicGraph::NodeIterator u, | ||||
|     void InsertEdgeBasedNode(NodeBasedDynamicGraph::NodeIterator u, | ||||
|                              NodeBasedDynamicGraph::NodeIterator v, | ||||
|                              NodeBasedDynamicGraph::EdgeIterator e1, | ||||
|         bool belongsToTinyComponent | ||||
|     ); | ||||
|                              bool belongsToTinyComponent); | ||||
| 
 | ||||
|     void BFSCompentExplorer( | ||||
|         std::vector<unsigned> & component_index_list, | ||||
|         std::vector<unsigned> & component_index_size | ||||
|     ) const; | ||||
| 
 | ||||
|     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 { | ||||
|     try | ||||
|     { | ||||
|         boost::filesystem::path p = boost::filesystem::temp_directory_path(); | ||||
|         boost::filesystem::space_info s = boost::filesystem::space( p ); | ||||
|         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