diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index d53bd152a..bbeb1222d 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -60,6 +60,7 @@ TrafficManager::TrafficManager(DataSource & dataSource, traffic::TrafficObserver & observer) : m_dataSource(dataSource) , m_countryParentNameGetterFn(countryParentNameGetter) + , m_openLrDecoder(m_dataSource, countryParentNameGetter) , m_getMwmsByRectFn(getMwmsByRectFn) , m_observer(observer) , m_currentDataVersion(0) @@ -403,8 +404,7 @@ void TrafficManager::InitializeDataSources(std::vector & dataS * If we batch-decode segments, we need to fix the [partner] segment IDs in the segment and path * structures to accept a TraFF message ID (string) rather than an integer. */ -void TrafficManager::DecodeMessage(openlr::OpenLRDecoder & decoder, - traffxml::TraffMessage & message, std::map & trafficCache) { if (message.m_location) @@ -439,7 +439,7 @@ void TrafficManager::DecodeMessage(openlr::OpenLRDecoder & decoder, // Decode the location into a path on the map. // One path per segment std::vector paths(segments.size()); - decoder.DecodeV3(segments, kNumDecoderThreads, paths); + m_openLrDecoder.DecodeV3(segments, kNumDecoderThreads, paths); for (size_t i = 0; i < paths.size(); i++) { @@ -547,22 +547,6 @@ void TrafficManager::ThreadRoutine() UpdateMessageCache(m_messageCache); LOG(LINFO, (m_messageCache.size(), "message(s) in cache")); - // initialize the decoder - /* - * Access to `DataSource` is not thread-safe. The main app, which works with - * `EditableDataSource` (as the map can be edited), wraps map operations into a - * `FeaturesLoaderGuard`. The OpenLR decoder expects one `FrozenDataSource` (a read-only - * subclass) per worker thread – which works as long as the map is not modified. - * Edits are not relevant to the OpenLR decoder. However, if the edits modify MWM files (rather - * than being stored separately), this might confuse the `FrozenDataSource`. In this case, we - * would need to rewrite the OpenLR decoder to work with a `FeaturesLoaderGuard` (which is - * probably the more elegant way to do this anyway). - */ - std::vector dataSources(kNumDecoderThreads); - // TODO test with data source from framework - InitializeDataSources(dataSources); - openlr::OpenLRDecoder decoder(dataSources, m_countryParentNameGetterFn); - /* * Map between country names and their colorings. * TODO use MwmId as map keys: @@ -577,7 +561,7 @@ void TrafficManager::ThreadRoutine() for (auto [id, message] : m_messageCache) { LOG(LINFO, (" ", id, ":", message)); - DecodeMessage(decoder, message, allMwmColoring); + DecodeMessage(message, allMwmColoring); } // set new coloring for MWMs diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index c52f1172d..c354e00fc 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -259,7 +259,7 @@ private: * @param message The message to decode. * @param trafficCache The cache in which all decoded paths with their speed groups will be stored. */ - void DecodeMessage(openlr::OpenLRDecoder &decoder, traffxml::TraffMessage & message, + void DecodeMessage(traffxml::TraffMessage & message, std::map & trafficCache); /** @@ -514,6 +514,13 @@ private: * Keys are message IDs, values are messages. */ std::map m_messageCache; + + /** + * @brief The OpenLR decoder instance. + * + * Used to decode TraFF locations into road segments on the map. + */ + openlr::OpenLRDecoder m_openLrDecoder; }; extern std::string DebugPrint(TrafficManager::TrafficState state); diff --git a/openlr/openlr_decoder.cpp b/openlr/openlr_decoder.cpp index 7a9df268d..aba779f8c 100644 --- a/openlr/openlr_decoder.cpp +++ b/openlr/openlr_decoder.cpp @@ -437,9 +437,9 @@ bool OpenLRDecoder::SegmentsFilter::Matches(LinearSegment const & segment) const } // OpenLRDecoder ----------------------------------------------------------------------------- -OpenLRDecoder::OpenLRDecoder(vector & dataSources, +OpenLRDecoder::OpenLRDecoder(DataSource & dataSource, CountryParentNameGetter const & countryParentNameGetter) - : m_dataSources(dataSources), m_countryParentNameGetter(countryParentNameGetter) + : m_dataSource(dataSource), m_countryParentNameGetter(countryParentNameGetter) { } @@ -490,9 +490,9 @@ void OpenLRDecoder::Decode(vector const & segments, vector stats(numThreads); vector workers; for (size_t i = 1; i < numThreads; ++i) - workers.emplace_back(worker, i, ref(m_dataSources[i]), ref(stats[i])); + workers.emplace_back(worker, i, ref(m_dataSource), ref(stats[i])); - worker(0 /* threadNum */, m_dataSources[0], stats[0]); + worker(0 /* threadNum */, m_dataSource, stats[0]); for (auto & worker : workers) worker.join(); diff --git a/openlr/openlr_decoder.hpp b/openlr/openlr_decoder.hpp index 9e612a29d..a7ee9e952 100644 --- a/openlr/openlr_decoder.hpp +++ b/openlr/openlr_decoder.hpp @@ -40,7 +40,7 @@ public: bool const m_multipointsOnly; }; - OpenLRDecoder(std::vector & dataSources, + OpenLRDecoder(DataSource & dataSource, CountryParentNameGetter const & countryParentNameGetter); /** @@ -62,7 +62,7 @@ private: void Decode(std::vector const & segments, uint32_t const numThreads, std::vector & paths); - std::vector & m_dataSources; + DataSource & m_dataSource; CountryParentNameGetter m_countryParentNameGetter; }; } // namespace openlr