diff --git a/routing/cross_mwm_road_graph.cpp b/routing/cross_mwm_road_graph.cpp index 2333b1a922..49e55c1d55 100644 --- a/routing/cross_mwm_road_graph.cpp +++ b/routing/cross_mwm_road_graph.cpp @@ -166,6 +166,7 @@ void CrossMwmGraph::GetOutgoingEdgesList(BorderCross const & v, TRoutingMappingPtr currentMapping = m_indexManager.GetMappingByName(v.toNode.mwmName); ASSERT(currentMapping->IsValid(), ()); currentMapping->LoadCrossContext(); + currentMapping->FreeFileIfPossible(); CrossRoutingContextReader const & currentContext = currentMapping->m_crossContext; auto inRange = currentContext.GetIngoingIterators(); diff --git a/routing/routing_mapping.cpp b/routing/routing_mapping.cpp index 46cb2222c9..a0a786a95b 100644 --- a/routing/routing_mapping.cpp +++ b/routing/routing_mapping.cpp @@ -52,7 +52,8 @@ RoutingMapping::RoutingMapping(string const & countryFile, MwmSet * pIndex) m_facadeCounter(0), m_crossContextLoaded(0), m_countryFile(countryFile), - m_error(IRouter::ResultCode::RouteFileNotExist) + m_error(IRouter::ResultCode::RouteFileNotExist), + m_pIndex(pIndex) { m_handle = pIndex->GetMwmHandleByCountryFile(CountryFile(countryFile)); if (!m_handle.IsAlive()) @@ -75,9 +76,22 @@ RoutingMapping::RoutingMapping(string const & countryFile, MwmSet * pIndex) return; } + m_mwmId = m_handle.GetId(); m_error = IRouter::ResultCode::NoError; } +void RoutingMapping::LoadFileIfNeed() +{ + if (!m_handle.IsAlive() && m_mwmId.IsAlive() && m_pIndex) + m_handle = m_pIndex->GetMwmHandleById(m_mwmId); +} + +void RoutingMapping::FreeFileIfPossible() +{ + if (m_handle.IsAlive() && m_mapCounter == 0 && m_facadeCounter == 0) + m_handle = MwmSet::MwmHandle(); +} + RoutingMapping::~RoutingMapping() { // Clear data while m_container is valid. @@ -88,6 +102,7 @@ RoutingMapping::~RoutingMapping() void RoutingMapping::Map() { + LoadFileIfNeed(); ++m_mapCounter; if (!m_segMapping.IsMapped()) { @@ -101,12 +116,14 @@ void RoutingMapping::Unmap() --m_mapCounter; if (m_mapCounter < 1 && m_segMapping.IsMapped()) m_segMapping.Unmap(); + FreeFileIfPossible(); } void RoutingMapping::LoadFacade() { if (!m_facadeCounter) { + LoadFileIfNeed(); m_dataFacade.Load(m_container); } ++m_facadeCounter; @@ -116,7 +133,10 @@ void RoutingMapping::FreeFacade() { --m_facadeCounter; if (!m_facadeCounter) + { + FreeFileIfPossible(); m_dataFacade.Clear(); + } } void RoutingMapping::LoadCrossContext() @@ -124,6 +144,8 @@ void RoutingMapping::LoadCrossContext() if (m_crossContextLoaded) return; + LoadFileIfNeed(); + if (m_container.IsExist(ROUTING_CROSS_CONTEXT_TAG)) { m_crossContext.Load(m_container.GetReader(ROUTING_CROSS_CONTEXT_TAG)); diff --git a/routing/routing_mapping.hpp b/routing/routing_mapping.hpp index 866de8ea9b..7e87b1fa0c 100644 --- a/routing/routing_mapping.hpp +++ b/routing/routing_mapping.hpp @@ -39,7 +39,7 @@ struct RoutingMapping void LoadCrossContext(); void FreeCrossContext(); - bool IsValid() const { return m_handle.IsAlive() && m_error == IRouter::ResultCode::NoError; } + bool IsValid() const { return m_mwmId.IsAlive() && m_error == IRouter::ResultCode::NoError; } IRouter::ResultCode GetError() const { return m_error; } @@ -49,9 +49,15 @@ struct RoutingMapping */ string const & GetCountryName() const { return m_countryFile; } - Index::MwmId const & GetMwmId() const { return m_handle.GetId(); } + Index::MwmId const & GetMwmId() const { return m_mwmId; } + + // Free file handles if it is possible. Works only if there is no mapped sections. Cross section + // will be valid after free. + void FreeFileIfPossible(); private: + void LoadFileIfNeed(); + size_t m_mapCounter; size_t m_facadeCounter; bool m_crossContextLoaded; @@ -59,6 +65,8 @@ private: FilesMappingContainer m_container; IRouter::ResultCode m_error; MwmSet::MwmHandle m_handle; + Index::MwmId m_mwmId; + MwmSet * m_pIndex; }; typedef shared_ptr TRoutingMappingPtr;