diff options
author | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2016-12-09 13:07:10 +0300 |
---|---|---|
committer | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2016-12-13 10:14:12 +0300 |
commit | 5a89f88c0380d8c8c6d903827d8f1195b650863e (patch) | |
tree | bf6c4d0374389a10d6f38fcfdf53e514a9f55d95 /map | |
parent | 657bd88190f8b5bc21ef06d8336f926c9abb23d0 (diff) |
Requesting traffic info for mwm under current possition and near current possition.
Diffstat (limited to 'map')
-rw-r--r-- | map/traffic_manager.cpp | 91 | ||||
-rw-r--r-- | map/traffic_manager.hpp | 57 |
2 files changed, 96 insertions, 52 deletions
diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 4e004245e3..d6d4f5479a 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -8,6 +8,8 @@ #include "indexer/ftypes_matcher.hpp" #include "indexer/scales.hpp" +#include "geometry/mercator.hpp" + #include "platform/platform.hpp" #include "3party/Alohalytics/src/alohalytics.h" @@ -120,8 +122,10 @@ void TrafficManager::Clear() { m_currentCacheSizeBytes = 0; m_mwmCache.clear(); - m_lastMwmsByRect.clear(); - m_activeMwms.clear(); + m_lastDrapeMwmsByRect.clear(); + m_lastRoutingMwmsByRect.clear(); + m_activeDrapeMwms.clear(); + m_activeRoutingMwms.clear(); m_requestedMwms.clear(); } @@ -168,7 +172,8 @@ void TrafficManager::Invalidate() if (!IsEnabled()) return; - m_lastMwmsByRect.clear(); + m_lastDrapeMwmsByRect.clear(); + m_lastRoutingMwmsByRect.clear(); if (m_currentModelView.second) UpdateViewport(m_currentModelView.first); @@ -176,48 +181,56 @@ void TrafficManager::Invalidate() UpdateMyPosition(m_currentPosition.first); } -void TrafficManager::UpdateViewport(ScreenBase const & screen) +void TrafficManager::UpdateActiveMwms(m2::RectD const & rect, + vector<MwmSet::MwmId> & lastMwmsByRect, + set<MwmSet::MwmId> & activeMwms) { - m_currentModelView = {screen, true /* initialized */}; - - if (!IsEnabled() || IsInvalidState()) + auto mwms = m_getMwmsByRectFn(rect); + if (lastMwmsByRect == mwms) return; - - if (df::GetZoomLevel(screen.GetScale()) < df::kRoadClass0ZoomLevel) - return; - - // Request traffic. - auto mwms = m_getMwmsByRectFn(screen.ClipRect()); - if (m_lastMwmsByRect == mwms) - return; - m_lastMwmsByRect = mwms; + lastMwmsByRect = mwms; { lock_guard<mutex> lock(m_mutex); - - m_activeMwms.clear(); + activeMwms.clear(); for (auto const & mwm : mwms) { if (mwm.IsAlive()) - m_activeMwms.insert(mwm); + activeMwms.insert(mwm); } - RequestTrafficData(); } } void TrafficManager::UpdateMyPosition(MyPosition const & myPosition) { + // Side of square around |myPosition|. Every mwm which is covered by the square + // will get traffic info. + double const kSquareSideM = 5000; m_currentPosition = {myPosition, true /* initialized */}; if (!IsEnabled() || IsInvalidState()) return; - // 1. Determine mwm's nearby "my position". + m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(myPosition.m_position, kSquareSideM); + // Request traffic. + UpdateActiveMwms(rect, m_lastRoutingMwmsByRect, m_activeRoutingMwms); - // 2. Request traffic for this mwm's. + // @TODO Do all routing stuff. +} + +void TrafficManager::UpdateViewport(ScreenBase const & screen) +{ + m_currentModelView = {screen, true /* initialized */}; - // 3. Do all routing stuff. + if (!IsEnabled() || IsInvalidState()) + return; + + if (df::GetZoomLevel(screen.GetScale()) < df::kRoadClass0ZoomLevel) + return; + + // Request traffic. + UpdateActiveMwms(screen.ClipRect(), m_lastDrapeMwmsByRect, m_activeDrapeMwms); } void TrafficManager::ThreadRoutine() @@ -300,14 +313,16 @@ void TrafficManager::RequestTrafficData(MwmSet::MwmId const & mwmId, bool force) void TrafficManager::RequestTrafficData() { - if (m_activeMwms.empty() || !IsEnabled() || IsInvalidState()) + if ((m_activeDrapeMwms.empty() && m_activeRoutingMwms.empty()) + || !IsEnabled() || IsInvalidState()) + { return; + } - for (auto const & mwmId : m_activeMwms) - { + ForEachActiveMwm([this](MwmSet::MwmId const & mwmId){ ASSERT(mwmId.IsAlive(), ()); RequestTrafficData(mwmId, false /* force */); - } + }); UpdateState(); } @@ -325,7 +340,8 @@ void TrafficManager::OnTrafficRequestFailed(traffic::TrafficInfo && info) if (info.GetAvailability() == traffic::TrafficInfo::Availability::Unknown && !it->second.m_isLoaded) { - if (m_activeMwms.find(info.GetMwmId()) != m_activeMwms.end()) + if (m_activeDrapeMwms.find(info.GetMwmId()) != m_activeDrapeMwms.cend() + || m_activeRoutingMwms.find(info.GetMwmId()) != m_activeRoutingMwms.cend()) { if (it->second.m_retriesCount < kMaxRetriesCount) RequestTrafficData(info.GetMwmId(), true /* force */); @@ -376,9 +392,20 @@ void TrafficManager::OnTrafficDataResponse(traffic::TrafficInfo && info) } } +void TrafficManager::UniteActiveMwms(set<MwmSet::MwmId> & activeMwms) const +{ + activeMwms.insert(m_activeDrapeMwms.cbegin(), m_activeDrapeMwms.cend()); + activeMwms.insert(m_activeRoutingMwms.cbegin(), m_activeRoutingMwms.cend()); +} + void TrafficManager::CheckCacheSize() { - if (m_currentCacheSizeBytes > m_maxCacheSizeBytes && m_mwmCache.size() > m_activeMwms.size()) + // Calculating number of different active mwms. + set<MwmSet::MwmId> activeMwms; + UniteActiveMwms(activeMwms); + size_t const activeMwmsSize = m_activeDrapeMwms.size(); + + if (m_currentCacheSizeBytes > m_maxCacheSizeBytes && m_mwmCache.size() > activeMwmsSize) { std::multimap<time_point<steady_clock>, MwmSet::MwmId> seenTimings; for (auto const & mwmInfo : m_mwmCache) @@ -386,7 +413,7 @@ void TrafficManager::CheckCacheSize() auto itSeen = seenTimings.begin(); while (m_currentCacheSizeBytes > m_maxCacheSizeBytes && - m_mwmCache.size() > m_activeMwms.size()) + m_mwmCache.size() > activeMwmsSize) { ClearCache(itSeen->second); ++itSeen; @@ -438,7 +465,7 @@ void TrafficManager::UpdateState() bool expiredData = false; bool noData = false; - for (auto const & mwmId : m_activeMwms) + ForEachActiveMwm([&](MwmSet::MwmId const & mwmId) { auto it = m_mwmCache.find(mwmId); ASSERT(it != m_mwmCache.end(), ()); @@ -464,7 +491,7 @@ void TrafficManager::UpdateState() { networkError = true; } - } + }); if (networkError || maxPassedTime >= kNetworkErrorTimeout) ChangeState(TrafficState::NetworkError); diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index 82a913535f..f29f4e888d 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -86,7 +86,28 @@ private: void OnTrafficDataResponse(traffic::TrafficInfo && info); void OnTrafficRequestFailed(traffic::TrafficInfo && info); + void UpdateActiveMwms(m2::RectD const & rect, vector<MwmSet::MwmId> & lastMwmsByRect, + set<MwmSet::MwmId> & activeMwms); + private: + struct CacheEntry + { + CacheEntry(); + CacheEntry(time_point<steady_clock> const & requestTime); + + bool m_isLoaded; + size_t m_dataSize; + + time_point<steady_clock> m_lastSeenTime; + time_point<steady_clock> m_lastRequestTime; + time_point<steady_clock> m_lastResponseTime; + + int m_retriesCount; + bool m_isWaitingForResponse; + + traffic::TrafficInfo::Availability m_lastAvailability; + }; + // This is a group of methods that haven't their own synchronization inside. void RequestTrafficData(); void RequestTrafficData(MwmSet::MwmId const & mwmId, bool force); @@ -101,6 +122,17 @@ private: bool IsInvalidState() const; bool IsEnabled() const; + void UniteActiveMwms(set<MwmSet::MwmId> & activeMwms) const; + + template <class F> + void ForEachActiveMwm(F && f) const + { + set<MwmSet::MwmId> activeMwms; + UniteActiveMwms(activeMwms); + for (MwmSet::MwmId const & mwmId : activeMwms) + f(mwmId); + } + GetMwmsByRectFn m_getMwmsByRectFn; traffic::TrafficObserver & m_observer; @@ -114,24 +146,6 @@ private: atomic<TrafficState> m_state; TrafficStateChangedFn m_onStateChangedFn; - struct CacheEntry - { - CacheEntry(); - CacheEntry(time_point<steady_clock> const & requestTime); - - bool m_isLoaded; - size_t m_dataSize; - - time_point<steady_clock> m_lastSeenTime; - time_point<steady_clock> m_lastRequestTime; - time_point<steady_clock> m_lastResponseTime; - - int m_retriesCount; - bool m_isWaitingForResponse; - - traffic::TrafficInfo::Availability m_lastAvailability; - }; - size_t m_maxCacheSizeBytes; size_t m_currentCacheSizeBytes = 0; @@ -140,8 +154,11 @@ private: bool m_isRunning; condition_variable m_condition; - vector<MwmSet::MwmId> m_lastMwmsByRect; - set<MwmSet::MwmId> m_activeMwms; + vector<MwmSet::MwmId> m_lastDrapeMwmsByRect; + set<MwmSet::MwmId> m_activeDrapeMwms; + vector<MwmSet::MwmId> m_lastRoutingMwmsByRect; + set<MwmSet::MwmId> m_activeRoutingMwms; + // The ETag or entity tag is part of HTTP, the protocol for the World Wide Web. // It is one of several mechanisms that HTTP provides for web cache validation, // which allows a client to make conditional requests. |