diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 160183b9bb..7716e6d507 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -328,9 +328,9 @@ void BuildRoutingIndex(string const & baseDir, string const & countryName, strin for (auto i = in.first; i < in.second; ++i) for (auto j = out.first; j < out.second; ++j) { - if (*res != INVALID_EDGE_WEIGHT) - crossContext.setAdjacencyCost(i, j, *res); - ++res; + EdgeWeight const & edgeWeigth = *(res++); + if (edgeWeigth != INVALID_EDGE_WEIGHT && edgeWeigth > 0) + crossContext.setAdjacencyCost(i, j, edgeWeigth); } LOG(LINFO, ("Calculation of weight map between outgoing nodes DONE")); } diff --git a/routing/osrm2feature_map.cpp b/routing/osrm2feature_map.cpp index f36a0db36f..e35e804ab4 100644 --- a/routing/osrm2feature_map.cpp +++ b/routing/osrm2feature_map.cpp @@ -122,8 +122,6 @@ void OsrmFtSegMapping::Load(FilesMappingContainer & cont) } } - Map(cont); - m_backwardIndex.Construct(*this, m_offsets.back().m_nodeId, cont); } @@ -368,7 +366,7 @@ bool OsrmFtSegBackwardIndex::Load(string const & nodesFileName, string const & b return true; } -void OsrmFtSegBackwardIndex::Construct(const OsrmFtSegMapping & mapping, const uint32_t maxNodeId, FilesMappingContainer & routingFile) +void OsrmFtSegBackwardIndex::Construct(OsrmFtSegMapping & mapping, const uint32_t maxNodeId, FilesMappingContainer & routingFile) { Clear(); @@ -391,19 +389,23 @@ void OsrmFtSegBackwardIndex::Construct(const OsrmFtSegMapping & mapping, const u if (Load(bitsFileName, nodesFileName)) return; + mapping.Map(routingFile); + // Generate temporary index to speedup processing unordered_multimap temporaryBackwardIndex; for (uint32_t i = 0; i < maxNodeId; ++i) { auto indexes = mapping.GetSegmentsRange(i); - for (size_t j = indexes.first; j != indexes.second; ++j) + for (; indexes.first != indexes.second; ++indexes.first) { OsrmMappingTypes::FtSeg seg; - mapping.GetSegmentByIndex(j, seg); + mapping.GetSegmentByIndex(indexes.first, seg); temporaryBackwardIndex.insert(make_pair(seg.m_fid, i)); } } + mapping.Unmap(); + // Create final index vector inIndex(m_table->size(), false); vector nodeIds; diff --git a/routing/osrm2feature_map.hpp b/routing/osrm2feature_map.hpp index 08bfc450a8..96ba0367f0 100644 --- a/routing/osrm2feature_map.hpp +++ b/routing/osrm2feature_map.hpp @@ -108,7 +108,7 @@ class OsrmFtSegBackwardIndex bool Load(string const & nodesFileName, string const & bitsFileName); public: - void Construct(OsrmFtSegMapping const & mapping, uint32_t const maxNodeId, FilesMappingContainer & routingFile); + void Construct(OsrmFtSegMapping & mapping, uint32_t const maxNodeId, FilesMappingContainer & routingFile); TNodesList const & GetNodeIdByFid(uint32_t const fid) const; diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 39e4800761..4b2f01d21c 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -723,8 +723,8 @@ public: ASSERT(it != income_iterators.second, ()); - const size_t targetNumber = distance(income_iterators.first, it); - const EdgeWeight targetWeight = m_weights[targetNumber]; + size_t const targetNumber = distance(income_iterators.first, it); + EdgeWeight const targetWeight = m_weights[targetNumber]; if (targetWeight == INVALID_EDGE_WEIGHT) { outCrossTask.weight = INVALID_EDGE_WEIGHT; @@ -750,7 +750,6 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt { // Check if target is a neighbour startMapping->LoadCrossContext(); - MY_SCOPE_GUARD(startMappingGuard, [&]() {startMapping->FreeCrossContext();}); auto out_iterators = startMapping->m_crossContext.GetOutgoingIterators(); for (auto i = out_iterators.first; i != out_iterators.second; ++i) if (startMapping->m_crossContext.getOutgoingMwmName(i->m_outgoingIndex) == targetMapping->GetName()) @@ -808,6 +807,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt if (startMapping->GetName() == targetMapping->GetName()) { LOG(LINFO, ("Single mwm routing case")); + m_indexManager.ForEachMapping([](pair const & indexPair){indexPair.second->FreeCrossContext();}); if (!FindSingleRoute(startTask, m_CachedTargetTask, startMapping->m_dataFacade, routingResult)) { return RouteNotFound; @@ -837,9 +837,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt { LOG(LINFO, ("Multiple mwm routing case")); startMapping->LoadCrossContext(); - MY_SCOPE_GUARD(startMappingGuard, [&]() {startMapping->FreeCrossContext();}); targetMapping->LoadCrossContext(); - MY_SCOPE_GUARD(targetMappingGuard, [&]() {targetMapping->FreeCrossContext();}); // Check if mwms are neighbours /* @@ -939,7 +937,6 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt if (!nextMapping->IsValid()) continue; 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) @@ -986,7 +983,6 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt ASSERT(currentMapping->IsValid(), ()); 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(); @@ -1004,12 +1000,10 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt // find outs for (auto oit = current_out_iterators.first; oit != current_out_iterators.second; ++oit) { - const EdgeWeight outWeight = currentContext.getAdjacencyCost(iit, oit); - if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT) + EdgeWeight const outWeight = currentContext.getAdjacencyCost(iit, oit); + if (outWeight != INVALID_CONTEXT_EDGE_WEIGHT && outWeight != 0) { - /// @todo Investigate this assert in route from Moscow to Madrid. - /// France-Aquitaine hase zero weight. - //ASSERT(outWeight > 0, ()); + ASSERT(outWeight > 0, ("Looks' like .routing file is corrupted!")); if (getPathWeight(topTask)+outWeight >= finalWeight) continue; @@ -1030,7 +1024,6 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt checkedOuts.insert(outNode); nextMapping->LoadCrossContext(); - MY_SCOPE_GUARD(nextMappingGuard, [&]() {nextMapping->FreeCrossContext();}); size_t nextNodeId = FindNextMwmNode(*oit, nextMapping); if(nextNodeId == INVALID_NODE_ID) continue; @@ -1052,7 +1045,7 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt OsrmRouter::RoutePathCross targetCross; if(targetFinder.MakeLastCrossSegment(nextNodeId, targetCross)) { - const EdgeWeight newWeight = getPathWeight(tmpPath) + targetCross.weight; + EdgeWeight const newWeight = getPathWeight(tmpPath) + targetCross.weight; if (newWeight < finalWeight) { tmpPath.push_back(targetCross); @@ -1074,6 +1067,8 @@ OsrmRouter::ResultCode OsrmRouter::CalculateRouteImpl(m2::PointD const & startPt // 5. Make generate answer if (finalWeight < INVALID_EDGE_WEIGHT) { + // Manually free all cross context allocations before geometry unpacking + m_indexManager.ForEachMapping([](pair const & indexPair){indexPair.second->FreeCrossContext();}); auto code = MakeRouteFromCrossesPath(finalPath, route); LOG(LINFO, ("Make final route", timer.ElapsedNano())); timer.Reset(); diff --git a/routing/osrm_router.hpp b/routing/osrm_router.hpp index df5221fdf2..786b72c0b9 100644 --- a/routing/osrm_router.hpp +++ b/routing/osrm_router.hpp @@ -9,10 +9,11 @@ #include "../indexer/index.hpp" #include "../base/mutex.hpp" +#include "../std/atomic.hpp" #include "../std/function.hpp" #include "../std/numeric.hpp" -#include "../std/atomic.hpp" #include "../std/queue.hpp" +#include "../std/unordered_map.hpp" #include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h" #include "../3party/osrm/osrm-backend/DataStructures/RawRouteData.h" @@ -65,7 +66,7 @@ class RoutingIndexManager { CountryFileFnT m_countryFn; - map m_mapping; + unordered_map m_mapping; public: RoutingIndexManager(CountryFileFnT const & fn): m_countryFn(fn) {} @@ -73,6 +74,12 @@ public: RoutingMappingPtrT GetMappingByPoint(m2::PointD const & point, Index const * pIndex); RoutingMappingPtrT GetMappingByName(string const & fName, Index const * pIndex); + + template + void ForEachMapping(TFunctor toDo) + { + for_each(m_mapping.begin(), m_mapping.end(), toDo); + } void Clear() { diff --git a/routing/routing_mapping.cpp b/routing/routing_mapping.cpp index 579f9c0ab0..87d9263eb8 100644 --- a/routing/routing_mapping.cpp +++ b/routing/routing_mapping.cpp @@ -16,7 +16,7 @@ namespace routing { RoutingMapping::RoutingMapping(string const & fName, Index const * pIndex) - : m_mapCounter(0), m_facadeCounter(0), m_crossContextCounter(0), m_baseName(fName), + : m_mapCounter(0), m_facadeCounter(0), m_crossContextLoaded(0), m_baseName(fName), m_isValid(true), m_error(IRouter::ResultCode::NoError) { Platform & pl = GetPlatform(); @@ -90,17 +90,18 @@ void RoutingMapping::FreeFacade() void RoutingMapping::LoadCrossContext() { - if (!m_crossContextCounter) + if (!m_crossContextLoaded) if (m_container.IsExist(ROUTING_CROSS_CONTEXT_TAG)) + { m_crossContext.Load(m_container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); - ++m_crossContextCounter; + m_crossContextLoaded = true; + } } void RoutingMapping::FreeCrossContext() { - --m_crossContextCounter; - if (!m_crossContextCounter) - m_crossContext = CrossRoutingContextReader(); + m_crossContextLoaded = false; + m_crossContext = CrossRoutingContextReader(); } } diff --git a/routing/routing_mapping.h b/routing/routing_mapping.h index 96228309b3..ea32ac3dd2 100644 --- a/routing/routing_mapping.h +++ b/routing/routing_mapping.h @@ -48,7 +48,7 @@ struct RoutingMapping private: size_t m_mapCounter; size_t m_facadeCounter; - size_t m_crossContextCounter; + bool m_crossContextLoaded; string m_baseName; FilesMappingContainer m_container; Index::MwmId m_mwmId;