osrm-backend/Server/DataStructures/SharedDataFacade.h

386 lines
12 KiB
C
Raw Normal View History

2013-09-18 11:49:49 -04:00
/*
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.
*/
2013-10-25 13:31:39 -04:00
#ifndef SHARED_DATA_FACADE_H
#define SHARED_DATA_FACADE_H
2013-09-18 11:49:49 -04:00
2013-09-18 12:33:10 -04:00
//implements all data storage when shared memory is _NOT_ used
2013-10-25 13:31:39 -04:00
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
2013-09-18 11:49:49 -04:00
#include "BaseDataFacade.h"
2013-09-26 12:19:51 -04:00
#include "SharedDataType.h"
2013-09-18 11:49:49 -04:00
2013-09-18 12:33:10 -04:00
#include "../../DataStructures/StaticGraph.h"
2013-09-23 12:02:16 -04:00
#include "../../DataStructures/StaticRTree.h"
2013-09-20 15:05:47 -04:00
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/SimpleLogger.h"
2013-09-18 12:33:10 -04:00
2013-09-23 12:02:16 -04:00
#include <algorithm>
2013-09-18 11:49:49 -04:00
template<class EdgeDataT>
class SharedDataFacade : public BaseDataFacade<EdgeDataT> {
private:
typedef EdgeDataT EdgeData;
typedef BaseDataFacade<EdgeData> super;
typedef StaticGraph<EdgeData, true> QueryGraph;
typedef typename StaticGraph<EdgeData, true>::_StrNode GraphNode;
typedef typename StaticGraph<EdgeData, true>::_StrEdge GraphEdge;
typedef typename QueryGraph::InputEdge InputEdge;
typedef typename super::RTreeLeaf RTreeLeaf;
typedef typename StaticRTree<RTreeLeaf, true>::TreeNode RTreeNode;
2013-09-23 12:02:16 -04:00
2013-09-26 12:19:51 -04:00
SharedDataLayout * data_layout;
char * shared_memory;
SharedDataType * data_type_ptr;
2013-10-25 13:31:39 -04:00
SharedDataType CURRENT_LAYOUT;
SharedDataType CURRENT_DATA;
2013-09-26 12:19:51 -04:00
2013-09-23 12:02:16 -04:00
unsigned m_check_sum;
unsigned m_number_of_nodes;
boost::shared_ptr<QueryGraph> m_query_graph;
boost::shared_ptr<SharedMemory> m_layout_memory;
boost::shared_ptr<SharedMemory> m_large_memory;
2013-09-23 12:02:16 -04:00
std::string m_timestamp;
ShM<FixedPointCoordinate, true>::vector m_coordinate_list;
ShM<NodeID, true>::vector m_via_node_list;
ShM<unsigned, true>::vector m_name_ID_list;
ShM<TurnInstruction, true>::vector m_turn_instruction_list;
ShM<char, true>::vector m_names_char_list;
ShM<unsigned, true>::vector m_name_begin_indices;
2013-10-25 13:31:39 -04:00
boost::shared_ptr<StaticRTree<RTreeLeaf, true> > m_static_rtree;
2013-09-23 12:02:16 -04:00
2013-10-25 13:31:39 -04:00
// SharedDataFacade() { }
2013-09-23 12:02:16 -04:00
void LoadTimestamp() {
2013-09-26 12:19:51 -04:00
char * timestamp_ptr = shared_memory + data_layout->GetTimeStampOffset();
m_timestamp.resize(data_layout->timestamp_length);
std::copy(
timestamp_ptr,
timestamp_ptr+data_layout->timestamp_length,
m_timestamp.begin()
);
2013-09-23 12:02:16 -04:00
}
void LoadRTree(
const boost::filesystem::path & file_index_path
) {
2013-10-25 13:31:39 -04:00
SimpleLogger().Write() << "loading fileindex from " << file_index_path;
2013-09-26 12:19:51 -04:00
RTreeNode * tree_ptr = (RTreeNode *)(
shared_memory + data_layout->GetRSearchTreeOffset()
2013-09-23 12:02:16 -04:00
);
2013-10-25 13:31:39 -04:00
m_static_rtree = boost::make_shared<StaticRTree<RTreeLeaf, true> >(
tree_ptr,
2013-09-26 12:19:51 -04:00
data_layout->r_search_tree_size,
file_index_path
);
2013-09-23 12:02:16 -04:00
}
void LoadGraph() {
2013-09-26 12:19:51 -04:00
m_number_of_nodes = data_layout->graph_node_list_size;
GraphNode * graph_nodes_ptr = (GraphNode *)(
shared_memory + data_layout->GetGraphNodeListOffset()
2013-09-23 12:02:16 -04:00
);
2013-09-26 12:19:51 -04:00
GraphEdge * graph_edges_ptr = (GraphEdge *)(
shared_memory + data_layout->GetGraphEdgeListOffsett()
2013-09-23 12:02:16 -04:00
);
2013-09-26 12:19:51 -04:00
typename ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr,
data_layout->graph_node_list_size
);
typename ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr,
data_layout->graph_edge_list_size
);
m_query_graph.reset(
new QueryGraph(node_list, edge_list)
2013-09-23 12:02:16 -04:00
);
}
void LoadNodeAndEdgeInformation() {
2013-09-26 12:19:51 -04:00
FixedPointCoordinate * coordinate_list_ptr = (FixedPointCoordinate *)(
shared_memory + data_layout->GetCoordinateListOffset()
2013-09-23 12:02:16 -04:00
);
typename ShM<FixedPointCoordinate, true>::vector coordinate_list(
coordinate_list_ptr,
2013-09-26 12:19:51 -04:00
data_layout->coordinate_list_size
);
m_coordinate_list.swap( coordinate_list );
2013-09-26 12:19:51 -04:00
TurnInstruction * turn_instruction_list_ptr = (TurnInstruction *)(
shared_memory + data_layout->GetTurnInstructionListOffset()
);
typename ShM<TurnInstruction, true>::vector turn_instruction_list(
turn_instruction_list_ptr,
2013-09-26 12:19:51 -04:00
data_layout->turn_instruction_list_size
);
m_turn_instruction_list.swap(turn_instruction_list);
2013-09-26 12:19:51 -04:00
unsigned * name_id_list_ptr = (unsigned *)(
shared_memory + data_layout->GetNameIDListOffset()
);
typename ShM<unsigned, true>::vector name_id_list(
name_id_list_ptr,
data_layout->name_id_list_size
);
m_name_ID_list.swap(name_id_list);
2013-09-23 12:02:16 -04:00
}
void LoadViaNodeList() {
2013-09-26 12:19:51 -04:00
NodeID * via_node_list_ptr = (NodeID *)(
shared_memory + data_layout->GetViaNodeListOffset()
);
typename ShM<NodeID, true>::vector via_node_list(
via_node_list_ptr,
2013-09-26 12:19:51 -04:00
data_layout->via_node_list_size
);
m_via_node_list.swap(via_node_list);
}
void LoadNames() {
2013-09-26 12:19:51 -04:00
unsigned * street_names_index_ptr = (unsigned *)(
shared_memory + data_layout->GetNameIndexOffset()
);
typename ShM<unsigned, true>::vector name_begin_indices(
street_names_index_ptr,
data_layout->name_index_list_size
);
m_name_begin_indices.swap(name_begin_indices);
2013-09-26 12:19:51 -04:00
char * names_list_ptr = (char *)(
shared_memory + data_layout->GetNameListOffset()
);
typename ShM<char, true>::vector names_char_list(
names_list_ptr,
data_layout->name_char_list_size
);
m_names_char_list.swap(names_char_list);
}
2013-09-18 11:49:49 -04:00
public:
2013-10-25 13:31:39 -04:00
SharedDataFacade( ) {
data_type_ptr = (SharedDataType *)SharedMemoryFactory::Get(
CURRENT_REGIONS,
2*sizeof(SharedDataType),
false,
false
)->Ptr();
2013-09-23 12:02:16 -04:00
2013-10-25 13:31:39 -04:00
CURRENT_LAYOUT = LAYOUT_NONE;
CURRENT_DATA = DATA_NONE;
2013-09-26 12:19:51 -04:00
SimpleLogger().Write() << "new shared facade";
2013-10-25 13:31:39 -04:00
//load data
CheckAndReloadFacade();
}
2013-09-26 12:19:51 -04:00
2013-10-25 13:31:39 -04:00
void CheckAndReloadFacade() {
if(
CURRENT_LAYOUT != data_type_ptr[0] ||
CURRENT_DATA != data_type_ptr[1]
) {
// release the previous shared memory segments
SharedMemory::Remove(CURRENT_LAYOUT);
SharedMemory::Remove(CURRENT_DATA);
2013-10-25 13:31:39 -04:00
CURRENT_LAYOUT = data_type_ptr[0];
CURRENT_DATA = data_type_ptr[1];
m_layout_memory.reset( SharedMemoryFactory::Get(CURRENT_LAYOUT) );
2013-10-25 13:31:39 -04:00
data_layout = (SharedDataLayout *)(
m_layout_memory->Ptr()
2013-10-25 13:31:39 -04:00
);
boost::filesystem::path ram_index_path(data_layout->ram_index_file_name);
if( !boost::filesystem::exists(ram_index_path) ) {
throw OSRMException("no leaf index file given in ini file");
}
m_large_memory.reset( SharedMemoryFactory::Get(CURRENT_DATA) );
2013-10-25 13:31:39 -04:00
shared_memory = (char *)(
m_large_memory->Ptr()
2013-10-25 13:31:39 -04:00
);
SimpleLogger().Write(logDEBUG) << "(re-)getting data from shared memory";
2013-10-25 13:31:39 -04:00
LoadGraph();
LoadNodeAndEdgeInformation();
LoadRTree(ram_index_path);
LoadTimestamp();
LoadViaNodeList();
LoadNames();
data_layout->PrintInformation();
2013-10-25 13:31:39 -04:00
} else {
SimpleLogger().Write(logDEBUG) << "using previously loaded data";
}
}
2013-09-18 11:49:49 -04:00
2013-10-25 13:31:39 -04:00
2013-09-18 11:49:49 -04:00
//search graph access
2013-09-23 12:02:16 -04:00
unsigned GetNumberOfNodes() const {
return m_query_graph->GetNumberOfNodes();
}
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
unsigned GetNumberOfEdges() const {
return m_query_graph->GetNumberOfEdges();
}
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
unsigned GetOutDegree( const NodeID n ) const {
return m_query_graph->GetOutDegree(n);
}
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
NodeID GetTarget( const EdgeID e ) const {
return m_query_graph->GetTarget(e); }
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
EdgeDataT &GetEdgeData( const EdgeID e ) {
return m_query_graph->GetEdgeData(e);
}
2013-09-18 11:49:49 -04:00
2013-09-23 13:00:08 -04:00
// const EdgeDataT &GetEdgeData( const EdgeID e ) const {
// return m_query_graph->GetEdgeData(e);
// }
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
EdgeID BeginEdges( const NodeID n ) const {
return m_query_graph->BeginEdges(n);
}
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
EdgeID EndEdges( const NodeID n ) const {
return m_query_graph->EndEdges(n);
}
2013-09-18 11:49:49 -04:00
//searches for a specific edge
2013-09-23 12:02:16 -04:00
EdgeID FindEdge( const NodeID from, const NodeID to ) const {
return m_query_graph->FindEdge(from, to);
}
2013-09-18 11:49:49 -04:00
EdgeID FindEdgeInEitherDirection(
const NodeID from,
const NodeID to
2013-09-23 12:02:16 -04:00
) const {
return m_query_graph->FindEdgeInEitherDirection(from, to);
}
2013-09-18 11:49:49 -04:00
EdgeID FindEdgeIndicateIfReverse(
const NodeID from,
const NodeID to,
bool & result
2013-09-23 12:02:16 -04:00
) const {
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
}
2013-09-18 11:49:49 -04:00
//node and edge information access
FixedPointCoordinate GetCoordinateOfNode(
const unsigned id
2013-09-23 12:02:16 -04:00
) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
};
2013-09-18 11:49:49 -04:00
TurnInstruction GetTurnInstructionForEdgeID(
const unsigned id
2013-09-23 12:02:16 -04:00
) const {
return m_turn_instruction_list.at(id);
}
2013-09-18 11:49:49 -04:00
bool LocateClosestEndPointForCoordinate(
const FixedPointCoordinate& input_coordinate,
FixedPointCoordinate& result,
const unsigned zoom_level = 18
2013-09-23 12:02:16 -04:00
) const {
return m_static_rtree->LocateClosestEndPointForCoordinate(
input_coordinate,
result,
zoom_level
);
}
2013-09-18 11:49:49 -04:00
bool FindPhantomNodeForCoordinate(
const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
2013-09-23 12:02:16 -04:00
) const {
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
);
}
2013-09-18 11:49:49 -04:00
2013-09-23 12:02:16 -04:00
unsigned GetCheckSum() const { return m_check_sum; }
2013-09-18 11:49:49 -04:00
unsigned GetNameIndexFromEdgeID(const unsigned id) const {
return m_name_ID_list.at(id);
};
2013-09-18 11:49:49 -04:00
void GetName( const unsigned name_id, std::string & result ) const {
if(UINT_MAX == name_id) {
result = "";
return;
}
BOOST_ASSERT_MSG(
name_id < m_name_begin_indices.size(),
"name id too high"
);
unsigned begin_index = m_name_begin_indices[name_id];
unsigned end_index = m_name_begin_indices[name_id+1];
BOOST_ASSERT_MSG(
begin_index < m_names_char_list.size(),
"begin index of name too high"
);
BOOST_ASSERT_MSG(
end_index < m_names_char_list.size(),
"end index of name too high"
);
BOOST_ASSERT_MSG(begin_index <= end_index, "string ends before begin");
result.clear();
result.resize(end_index - begin_index);
std::copy(
m_names_char_list.begin() + begin_index,
m_names_char_list.begin() + end_index,
result.begin()
);
}
2013-09-19 12:55:49 -04:00
std::string GetTimestamp() const {
2013-09-23 12:02:16 -04:00
return m_timestamp;
}
2013-09-18 11:49:49 -04:00
};
2013-10-25 13:31:39 -04:00
#endif // SHARED_DATA_FACADE_H