From de87caefc742945159a98d6353bb61bf323eaef7 Mon Sep 17 00:00:00 2001 From: Lev Dragunov Date: Mon, 2 Mar 2015 17:38:29 +0300 Subject: [PATCH] Extracting cross routing section from routing facade --- routing/osrm_data_facade.hpp | 16 ------ routing/osrm_router.cpp | 104 +++++++--------------------------- routing/osrm_router.hpp | 64 +-------------------- routing/routing.pro | 16 +++--- routing/routing_mapping.cpp | 106 +++++++++++++++++++++++++++++++++++ routing/routing_mapping.h | 79 ++++++++++++++++++++++++++ 6 files changed, 216 insertions(+), 169 deletions(-) create mode 100644 routing/routing_mapping.cpp create mode 100644 routing/routing_mapping.h diff --git a/routing/osrm_data_facade.hpp b/routing/osrm_data_facade.hpp index 5522c678f9..fd2fd10a83 100644 --- a/routing/osrm_data_facade.hpp +++ b/routing/osrm_data_facade.hpp @@ -4,8 +4,6 @@ #include "../defines.hpp" - - #include "../coding/file_container.hpp" #include "../coding/read_write_utils.hpp" @@ -230,7 +228,6 @@ public: template class OsrmDataFacade : public OsrmRawDataFacade { typedef OsrmRawDataFacade super; - CrossRoutingContextReader m_crossContext; FilesMappingContainer::Handle m_handleEdgeData; FilesMappingContainer::Handle m_handleEdgeId; @@ -261,14 +258,6 @@ public: LoadRawData(m_handleEdgeData.GetData(), m_handleEdgeId.GetData(), m_handleShortcuts.GetData(), m_handleFanoMatrix.GetData()); - if (container.IsExist(ROUTING_CROSS_CONTEXT_TAG)) - { - m_crossContext.Load(container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); - } - else - { - //LOG(LINFO, ("Old routing file version! Have no crossMwm information!")); - } } void Clear() @@ -279,11 +268,6 @@ public: m_handleShortcuts.Unmap(); m_handleFanoMatrix.Unmap(); } - - CrossRoutingContextReader const & getRoutingContext() - { - return m_crossContext; - } }; } diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 9c141b259c..0477f0f06f 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -11,14 +11,14 @@ #include "../indexer/mercator.hpp" #include "../indexer/index.hpp" #include "../indexer/scales.hpp" -#include "../indexer/mwm_version.hpp" #include "../indexer/search_string_utils.hpp" #include "../coding/reader_wrapper.hpp" #include "../base/logging.hpp" -#include "../base/timer.hpp" #include "../base/math.hpp" +#include "../base/scope_guard.hpp" +#include "../base/timer.hpp" #include "../std/algorithm.hpp" @@ -361,76 +361,7 @@ RoutingMappingPtrT RoutingIndexManager::GetMappingByName(string const & fName, I return new_mapping; } -RoutingMapping::RoutingMapping(string const & fName, Index const * pIndex) - : m_mapCounter(0), m_facadeCounter(0), m_baseName(fName), - m_isValid(true), m_error(IRouter::ResultCode::NoError) -{ - Platform & pl = GetPlatform(); - string const mwmName = m_baseName + DATA_FILE_EXTENSION; - string const fPath = pl.WritablePathForFile(mwmName + ROUTING_FILE_EXTENSION); - if (!pl.IsFileExistsByFullPath(fPath)) - { - m_isValid = false; - m_error = IRouter::ResultCode::RouteFileNotExist; - return; - } - // Open new container and check that mwm and routing have equal timestamp. - LOG(LDEBUG, ("Load routing index for file:", fPath)); - m_container.Open(fPath); - { - FileReader r1 = m_container.GetReader(VERSION_FILE_TAG); - ReaderSrc src1(r1); - ModelReaderPtr r2 = FilesContainerR(pl.GetReader(mwmName)).GetReader(VERSION_FILE_TAG); - ReaderSrc src2(r2.GetPtr()); - if (ver::ReadTimestamp(src1) != ver::ReadTimestamp(src2)) - { - m_container.Close(); - m_isValid = false; - m_error = IRouter::ResultCode::InconsistentMWMandRoute; - return; - } - m_segMapping.Load(m_container); - } - - m_mwmId = pIndex->GetMwmIdByName(mwmName); -} - -RoutingMapping::~RoutingMapping() -{ - // Clear data while m_container is valid. - m_dataFacade.Clear(); - m_segMapping.Clear(); - m_container.Close(); -} - -void RoutingMapping::Map() -{ - ++m_mapCounter; - if (!m_segMapping.IsMapped()) - m_segMapping.Map(m_container); -} - -void RoutingMapping::Unmap() -{ - --m_mapCounter; - if (m_mapCounter < 1 && m_segMapping.IsMapped()) - m_segMapping.Unmap(); -} - -void RoutingMapping::LoadFacade() -{ - if (!m_facadeCounter) - m_dataFacade.Load(m_container); - ++m_facadeCounter; -} - -void RoutingMapping::FreeFacade() -{ - --m_facadeCounter; - if (!m_facadeCounter) - m_dataFacade.Clear(); -} OsrmRouter::OsrmRouter(Index const * index, CountryFileFnT const & fn) : m_pIndex(index), m_indexManager(fn), m_isFinalChanged(false), @@ -644,8 +575,7 @@ size_t OsrmRouter::FindNextMwmNode(OutgoingCrossNode const & startNode, RoutingM { m2::PointD startPoint = startNode.m_point; - CrossRoutingContextReader const & targetContext = targetMapping->m_dataFacade.getRoutingContext(); - auto income_iters = targetContext.GetIngoingIterators(); + auto income_iters = targetMapping->m_crossContext.GetIngoingIterators(); for (auto i = income_iters.first; i < income_iters.second; ++i) { m2::PointD targetPoint = i->m_point; @@ -744,7 +674,7 @@ class OsrmRouter::LastCrossFinder public: LastCrossFinder(RoutingMappingPtrT & mapping, FeatureGraphNodeVecT const & targetTask) - : m_targetContext(mapping->m_dataFacade.getRoutingContext()), + : m_targetContext(mapping->m_crossContext), m_mwmName(mapping->GetName()) { auto income_iterators = m_targetContext.GetIngoingIterators(); @@ -889,10 +819,13 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt else //4.2 Multiple mwm case { LOG(LINFO, ("Multiple mwm routing case")); + startMapping->LoadCrossContext(); + MY_SCOPE_GUARD(startMappingGuard, [&]() {startMapping->FreeCrossContext();}); + targetMapping->LoadCrossContext(); + MY_SCOPE_GUARD(targetMappingGuard, [&]() {targetMapping->FreeCrossContext();}); // Load source data - CrossRoutingContextReader const & startContext = startMapping->m_dataFacade.getRoutingContext(); - auto out_iterators = startContext.GetOutgoingIterators(); + auto out_iterators = startMapping->m_crossContext.GetOutgoingIterators(); MultiroutingTaskPointT sources(1), targets(distance(out_iterators.first, out_iterators.second)); for (auto i = out_iterators.first; i < out_iterators.second; ++i) @@ -945,14 +878,14 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt continue; if (m_requestCancel) return Cancelled; - string const & nextMwm = startContext.getOutgoingMwmName((out_iterators.first+j)->m_outgoingIndex); + string const & nextMwm = startMapping->m_crossContext.getOutgoingMwmName((out_iterators.first+j)->m_outgoingIndex); RoutingMappingPtrT nextMapping; nextMapping = m_indexManager.GetMappingByName(nextMwm, m_pIndex); // If we don't this routing file, we skip this path if (!nextMapping->IsValid()) continue; - MappingGuard nextMappingGuard(nextMapping); - UNUSED_VALUE(nextMappingGuard); + nextMapping->LoadCrossContext(); + MY_SCOPE_GUARD(nextMappingGuard, [&]() {nextMapping->FreeCrossContext();}); size_t tNodeId = (out_iterators.first+j)->m_nodeId; size_t nextNodeId = FindNextMwmNode(*(out_iterators.first+j), nextMapping); if (nextNodeId == INVALID_NODE_ID) @@ -983,7 +916,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt } } - // Process tasks from tasks queu + // Process tasks from tasks queue if (!crossTasks.empty()) { while (getPathWeight(crossTasks.top())IsValid(), ()); - MappingGuard currentMappingGuard(currentMapping); - UNUSED_VALUE(currentMappingGuard); - CrossRoutingContextReader const & currentContext = currentMapping->m_dataFacade.getRoutingContext(); + currentMapping->LoadCrossContext(); + MY_SCOPE_GUARD(currentMappingGuard, [&]() {currentMapping->FreeCrossContext();}); + CrossRoutingContextReader const & currentContext = currentMapping->m_crossContext; auto current_in_iterators = currentContext.GetIngoingIterators(); auto current_out_iterators = currentContext.GetOutgoingIterators(); @@ -1032,13 +965,14 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt if (!nextMapping->IsValid()) continue; - MappingGuard nextMappingGuard(nextMapping); - UNUSED_VALUE(nextMappingGuard); size_t const tNodeId = oit->m_nodeId; auto const outNode = make_pair(tNodeId, currentMapping->GetName()); if (checkedOuts.find(outNode)!=checkedOuts.end()) continue; checkedOuts.insert(outNode); + + nextMapping->LoadCrossContext(); + MY_SCOPE_GUARD(nextMappingGuard, [&]() {nextMapping->FreeCrossContext();}); size_t nextNodeId = FindNextMwmNode(*oit, nextMapping); if(nextNodeId == INVALID_NODE_ID) continue; diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp index 1ced416f1f..2e3c7fab6b 100644 --- a/routing/osrm_router.hpp +++ b/routing/osrm_router.hpp @@ -1,9 +1,10 @@ #pragma once -#include "route.hpp" -#include "router.hpp" #include "osrm2feature_map.hpp" #include "osrm_data_facade.hpp" +#include "route.hpp" +#include "router.hpp" +#include "routing_mapping.h" #include "../indexer/index.hpp" #include "../base/mutex.hpp" @@ -57,65 +58,6 @@ struct RawRoutingResultT typedef vector MultipleRoutingResultT; - -/// Datamapping and facade for single MWM and MWM.routing file -struct RoutingMapping -{ - DataFacadeT m_dataFacade; - OsrmFtSegMapping m_segMapping; - - ///@param fName: mwm file path - RoutingMapping(string const & fName, Index const * pIndex); - - ~RoutingMapping(); - - void Map(); - - void Unmap(); - - void LoadFacade(); - - void FreeFacade(); - - bool IsValid() const {return m_isValid;} - - IRouter::ResultCode GetError() const {return m_error;} - - string GetName() const {return m_baseName;} - - Index::MwmId GetMwmId() const {return m_mwmId;} - -private: - size_t m_mapCounter; - size_t m_facadeCounter; - string m_baseName; - FilesMappingContainer m_container; - Index::MwmId m_mwmId; - bool m_isValid; - IRouter::ResultCode m_error; -}; - -typedef shared_ptr RoutingMappingPtrT; - -//! \brief The MappingGuard struct. Asks mapping to load all data on construction and free it on destruction -class MappingGuard -{ - RoutingMappingPtrT const m_mapping; - -public: - MappingGuard(RoutingMappingPtrT const mapping): m_mapping(mapping) - { - m_mapping->Map(); - m_mapping->LoadFacade(); - } - - ~MappingGuard() - { - m_mapping->Unmap(); - m_mapping->FreeFacade(); - } -}; - /*! Manager for loading, cashing and building routing indexes. * Builds and shares special routing contexts. */ diff --git a/routing/routing.pro b/routing/routing.pro index fc1fde7f04..a675ca1cac 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -12,21 +12,23 @@ INCLUDEPATH += $$ROOT_DIR/3party/jansson/src \ $$ROOT_DIR/3party/osrm/osrm-backend/Include SOURCES += \ - turns.cpp \ - route.cpp \ + cross_routing_context.cpp \ osrm_router.cpp \ osrm_online_router.cpp \ osrm2feature_map.cpp \ + route.cpp \ + routing_mapping.cpp \ + turns.cpp \ vehicle_model.cpp \ - cross_routing_context.cpp \ HEADERS += \ - turns.hpp \ - route.hpp \ - router.hpp \ + cross_routing_context.hpp \ osrm_router.hpp \ osrm_online_router.hpp \ osrm_data_facade.hpp \ osrm2feature_map.hpp \ + route.hpp \ + router.hpp \ + routing_mapping.h \ + turns.hpp \ vehicle_model.hpp \ - cross_routing_context.hpp \ diff --git a/routing/routing_mapping.cpp b/routing/routing_mapping.cpp new file mode 100644 index 0000000000..579f9c0ab0 --- /dev/null +++ b/routing/routing_mapping.cpp @@ -0,0 +1,106 @@ +#include "routing_mapping.h" + +#include "cross_routing_context.hpp" +#include "osrm2feature_map.hpp" +#include "osrm_data_facade.hpp" + +#include "../base/logging.hpp" + +#include "../coding/reader_wrapper.hpp" + +#include "../indexer/mwm_version.hpp" + +#include "../platform/platform.hpp" + +namespace routing +{ + +RoutingMapping::RoutingMapping(string const & fName, Index const * pIndex) + : m_mapCounter(0), m_facadeCounter(0), m_crossContextCounter(0), m_baseName(fName), + m_isValid(true), m_error(IRouter::ResultCode::NoError) +{ + Platform & pl = GetPlatform(); + string const mwmName = m_baseName + DATA_FILE_EXTENSION; + string const fPath = pl.WritablePathForFile(mwmName + ROUTING_FILE_EXTENSION); + if (!pl.IsFileExistsByFullPath(fPath)) + { + m_isValid = false; + m_error = IRouter::ResultCode::RouteFileNotExist; + return; + } + // Open new container and check that mwm and routing have equal timestamp. + LOG(LDEBUG, ("Load routing index for file:", fPath)); + m_container.Open(fPath); + { + FileReader r1 = m_container.GetReader(VERSION_FILE_TAG); + ReaderSrc src1(r1); + ModelReaderPtr r2 = FilesContainerR(pl.GetReader(mwmName)).GetReader(VERSION_FILE_TAG); + ReaderSrc src2(r2.GetPtr()); + + if (ver::ReadTimestamp(src1) != ver::ReadTimestamp(src2)) + { + m_container.Close(); + m_isValid = false; + m_error = IRouter::ResultCode::InconsistentMWMandRoute; + return; + } + } + + m_mwmId = pIndex->GetMwmIdByName(mwmName); +} + +RoutingMapping::~RoutingMapping() +{ + // Clear data while m_container is valid. + m_dataFacade.Clear(); + m_segMapping.Clear(); + m_container.Close(); +} + +void RoutingMapping::Map() +{ + ++m_mapCounter; + if (!m_segMapping.IsMapped()) + { + m_segMapping.Load(m_container); + m_segMapping.Map(m_container); + } +} + +void RoutingMapping::Unmap() +{ + --m_mapCounter; + if (m_mapCounter < 1 && m_segMapping.IsMapped()) + m_segMapping.Unmap(); +} + +void RoutingMapping::LoadFacade() +{ + if (!m_facadeCounter) + m_dataFacade.Load(m_container); + ++m_facadeCounter; +} + +void RoutingMapping::FreeFacade() +{ + --m_facadeCounter; + if (!m_facadeCounter) + m_dataFacade.Clear(); +} + +void RoutingMapping::LoadCrossContext() +{ + if (!m_crossContextCounter) + if (m_container.IsExist(ROUTING_CROSS_CONTEXT_TAG)) + m_crossContext.Load(m_container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); + ++m_crossContextCounter; +} + +void RoutingMapping::FreeCrossContext() +{ + --m_crossContextCounter; + if (!m_crossContextCounter) + m_crossContext = CrossRoutingContextReader(); +} + +} diff --git a/routing/routing_mapping.h b/routing/routing_mapping.h new file mode 100644 index 0000000000..96228309b3 --- /dev/null +++ b/routing/routing_mapping.h @@ -0,0 +1,79 @@ +#pragma once + +#include "osrm2feature_map.hpp" +#include "router.hpp" +#include "osrm_data_facade.hpp" + +#include "../indexer/index.hpp" + +#include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h" +#include "../3party/osrm/osrm-backend/DataStructures/RawRouteData.h" + +namespace routing +{ +typedef OsrmDataFacade DataFacadeT; + +/// Datamapping and facade for single MWM and MWM.routing file +struct RoutingMapping +{ + DataFacadeT m_dataFacade; + OsrmFtSegMapping m_segMapping; + CrossRoutingContextReader m_crossContext; + + ///@param fName: mwm file path + RoutingMapping(string const & fName, Index const * pIndex); + + ~RoutingMapping(); + + void Map(); + + void Unmap(); + + void LoadFacade(); + + void FreeFacade(); + + void LoadCrossContext(); + + void FreeCrossContext(); + + bool IsValid() const {return m_isValid;} + + IRouter::ResultCode GetError() const {return m_error;} + + string GetName() const {return m_baseName;} + + Index::MwmId GetMwmId() const {return m_mwmId;} + +private: + size_t m_mapCounter; + size_t m_facadeCounter; + size_t m_crossContextCounter; + string m_baseName; + FilesMappingContainer m_container; + Index::MwmId m_mwmId; + bool m_isValid; + IRouter::ResultCode m_error; +}; + +typedef shared_ptr RoutingMappingPtrT; + +//! \brief The MappingGuard struct. Asks mapping to load all data on construction and free it on destruction +class MappingGuard +{ + RoutingMappingPtrT const m_mapping; + +public: + MappingGuard(RoutingMappingPtrT const mapping): m_mapping(mapping) + { + m_mapping->Map(); + m_mapping->LoadFacade(); + } + + ~MappingGuard() + { + m_mapping->Unmap(); + m_mapping->FreeFacade(); + } +}; +}