From 8b8bcfe610ed47a1bc05bc3533eaf1a072bc29a3 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Fri, 15 Apr 2022 18:18:11 +0300 Subject: [PATCH] [routing] Added CrossMwmConnector::ForEachTransitSegmentId instead of raw getters. Signed-off-by: Viktor Govako --- routing/cross_mwm_connector.hpp | 31 ++++++++++++++---------- routing/cross_mwm_graph.cpp | 33 ++++++++++---------------- routing/cross_mwm_graph.hpp | 1 - routing/cross_mwm_index_graph.hpp | 20 ++++------------ routing/single_vehicle_world_graph.cpp | 11 ++++----- 5 files changed, 41 insertions(+), 55 deletions(-) diff --git a/routing/cross_mwm_connector.hpp b/routing/cross_mwm_connector.hpp index 5481b84f13..90decfe9a1 100644 --- a/routing/cross_mwm_connector.hpp +++ b/routing/cross_mwm_connector.hpp @@ -92,16 +92,17 @@ public: m_transitFeatureIdToSegmentId[featureId].emplace_back(segmentIdx); } - bool IsFeatureCrossMwmConnector(uint32_t featureId) const - { - return m_transitFeatureIdToSegmentId.find(featureId) != m_transitFeatureIdToSegmentId.cend(); - } - - std::vector const & GetTransitSegmentId(uint32_t featureId) const + template void ForEachTransitSegmentId(uint32_t featureId, FnT && fn) const { auto it = m_transitFeatureIdToSegmentId.find(featureId); - CHECK(it != m_transitFeatureIdToSegmentId.cend(), ()); - return it->second; + if (it != m_transitFeatureIdToSegmentId.cend()) + { + for (uint32_t segId : it->second) + { + if (fn(segId)) + break; + } + } } bool IsTransition(Segment const & segment, bool isOutgoing) const @@ -145,23 +146,29 @@ public: /// Actually, the fix is valid, because transition features can have segment = 1 when leaving MWM /// and segment = 2 when entering MWM due to *not precise* packed MWM borders. if (isEnter) - tIt = m_transitions.find(Key(featureId, segmentIdx + 1)); + tIt = m_transitions.find(Key(featureId, ++segmentIdx)); else if (segmentIdx > 0) - tIt = m_transitions.find(Key(featureId, segmentIdx - 1)); + tIt = m_transitions.find(Key(featureId, --segmentIdx)); if (tIt == m_transitions.cend()) return nullptr; } auto const & transition = tIt->second; - CHECK_EQUAL(transition.m_crossMwmId, crossMwmId, ("fId:", featureId, ", segId:", segmentIdx)); + ASSERT_EQUAL(transition.m_crossMwmId, crossMwmId, ("fId:", featureId, ", segId:", segmentIdx)); bool const isForward = transition.m_forwardIsEnter == isEnter; if (transition.m_oneWay && !isForward) return nullptr; Segment const & segment = isEnter ? GetEnter(transition.m_enterIdx) : GetExit(transition.m_exitIdx); - CHECK_EQUAL(segment.IsForward(), isForward, ("fId:", featureId, ", segId:", segmentIdx)); + + /// @todo Actually, we can avoid storing m_enters, m_exits, because we already have all Segment components: + /// Also can emulate segments iteration in Get{Ingoing/Outgoing}EdgeList. + ASSERT_EQUAL(segment.GetMwmId(), m_mwmId, ("fId:", featureId, ", segId:", segmentIdx)); + ASSERT_EQUAL(segment.GetFeatureId(), featureId, ("fId:", featureId, ", segId:", segmentIdx)); + ASSERT_EQUAL(segment.GetSegmentIdx(), segmentIdx, ("fId:", featureId, ", segId:", segmentIdx)); + ASSERT_EQUAL(segment.IsForward(), isForward, ("fId:", featureId, ", segId:", segmentIdx)); return &segment; } diff --git a/routing/cross_mwm_graph.cpp b/routing/cross_mwm_graph.cpp index e1b0eb4798..43b015152b 100644 --- a/routing/cross_mwm_graph.cpp +++ b/routing/cross_mwm_graph.cpp @@ -14,11 +14,10 @@ #include #include -using namespace routing; -using namespace std; - namespace routing { +using namespace std; + CrossMwmGraph::CrossMwmGraph(shared_ptr numMwmIds, shared_ptr> numMwmTree, shared_ptr vehicleModelFactory, @@ -176,25 +175,19 @@ void CrossMwmGraph::Clear() void CrossMwmGraph::GetTwinFeature(Segment const & segment, bool isOutgoing, vector & twins) { - std::vector const & transitSegmentIds = - m_crossMwmIndexGraph.GetTransitSegmentId(segment.GetMwmId(), segment.GetFeatureId()); - - for (auto transitSegmentId : transitSegmentIds) + m_crossMwmIndexGraph.ForEachTransitSegmentId(segment.GetMwmId(), segment.GetFeatureId(), + [&](uint32_t transitSegmentId) { - Segment const transitSegment(segment.GetMwmId(), segment.GetFeatureId(), - transitSegmentId, segment.IsForward()); + Segment const transitSegment(segment.GetMwmId(), segment.GetFeatureId(), transitSegmentId, segment.IsForward()); - if (!IsTransition(transitSegment, isOutgoing)) - continue; - - GetTwins(transitSegment, isOutgoing, twins); - break; - } -} - -bool CrossMwmGraph::IsFeatureTransit(NumMwmId numMwmId, uint32_t featureId) -{ - return m_crossMwmIndexGraph.IsFeatureTransit(numMwmId, featureId); + if (IsTransition(transitSegment, isOutgoing)) + { + // Get twins and exit. + GetTwins(transitSegment, isOutgoing, twins); + return true; + } + return false; + }); } CrossMwmGraph::MwmStatus CrossMwmGraph::GetMwmStatus(NumMwmId numMwmId, diff --git a/routing/cross_mwm_graph.hpp b/routing/cross_mwm_graph.hpp index 51e11f0805..6f95cf1435 100644 --- a/routing/cross_mwm_graph.hpp +++ b/routing/cross_mwm_graph.hpp @@ -102,7 +102,6 @@ public: return m_crossMwmIndexGraph.GetTransitions(numMwmId, isEnter); } - bool IsFeatureTransit(NumMwmId numMwmId, uint32_t featureId); /// \brief Checks whether feature where |segment| is placed is a cross mwm connector. /// If yes twin-segments are saved to |twins|. void GetTwinFeature(Segment const & segment, bool isOutgoing, std::vector & twins); diff --git a/routing/cross_mwm_index_graph.hpp b/routing/cross_mwm_index_graph.hpp index 0e177e6754..fd16311162 100644 --- a/routing/cross_mwm_index_graph.hpp +++ b/routing/cross_mwm_index_graph.hpp @@ -84,14 +84,9 @@ public: return c.IsTransition(s, isOutgoing); } - bool IsFeatureTransit(NumMwmId numMwmId, uint32_t featureId) + template void ForEachTransitSegmentId(NumMwmId numMwmId, uint32_t featureId, FnT && fn) { - return GetCrossMwmConnectorWithTransitions(numMwmId).IsFeatureCrossMwmConnector(featureId); - } - - std::vector const & GetTransitSegmentId(NumMwmId numMwmId, uint32_t featureId) - { - return GetCrossMwmConnectorWithTransitions(numMwmId).GetTransitSegmentId(featureId); + GetCrossMwmConnectorWithTransitions(numMwmId).ForEachTransitSegmentId(featureId, fn); } /// \brief Fills |twins| based on transitions defined in cross_mwm section. @@ -273,15 +268,10 @@ private: MwmValue const * value = handle.GetValue(); CHECK(value != nullptr, ("Country file:", m_numMwmIds->GetFile(numMwmId))); - FilesContainerR::TReader const reader = - FilesContainerR::TReader(connector::GetReader(value->m_cont)); + FilesContainerR::TReader reader(connector::GetReader(value->m_cont)); ReaderSourceFile src(reader); - auto it = m_connectors.find(numMwmId); - if (it == m_connectors.end()) - it = m_connectors - .emplace(numMwmId, CrossMwmConnector( - numMwmId, connector::GetFeaturesOffset())) - .first; + auto it = m_connectors.try_emplace( + numMwmId, CrossMwmConnector(numMwmId, connector::GetFeaturesOffset())).first; fn(m_vehicleType, it->second, src); return it->second; diff --git a/routing/single_vehicle_world_graph.cpp b/routing/single_vehicle_world_graph.cpp index 915e7150d0..ced6a133a4 100644 --- a/routing/single_vehicle_world_graph.cpp +++ b/routing/single_vehicle_world_graph.cpp @@ -46,18 +46,15 @@ void SingleVehicleWorldGraph::CheckAndProcessTransitFeatures(Segment const & par { JointSegment const & target = jointEdges[i].GetTarget(); - NumMwmId const edgeMwmId = target.GetMwmId(); - - if (!m_crossMwmGraph->IsFeatureTransit(edgeMwmId, target.GetFeatureId())) + vector twins; + m_crossMwmGraph->GetTwinFeature(target.GetSegment(true /* start */), isOutgoing, twins); + if (twins.empty()) { - ASSERT_EQUAL(mwmId, edgeMwmId, ()); + ASSERT_EQUAL(mwmId, target.GetMwmId(), ()); continue; } auto & currentIndexGraph = GetIndexGraph(mwmId); - - vector twins; - m_crossMwmGraph->GetTwinFeature(target.GetSegment(true /* start */), isOutgoing, twins); for (auto const & twin : twins) { NumMwmId const twinMwmId = twin.GetMwmId();