/
renath
/
organicmaps
Обзор
Документация
Войти
/
renath
/
organicmaps
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
generator/translators_pool.cpp
81 строка
2 KB
Alexander Borsuk
clang-format
24 июл 2025, 15:48
24 июл 2025, 15:48
15b66d5
Код
Авторство
О чём код?
#include "generator/translators_pool.hpp" #include <future> namespace generator { TranslatorsPool::TranslatorsPool(std::shared_ptr<TranslatorInterface> const & original, size_t threadCount) : m_threadPool(threadCount) { CHECK_GREATER_OR_EQUAL(threadCount, 1, ()); m_translators.Push(original); for (size_t i = 1; i < threadCount; ++i) m_translators.Push(original->Clone()); } void TranslatorsPool::Emit(std::vector<OsmElement> && elements) { std::shared_ptr<TranslatorInterface> translator; m_translators.WaitAndPop(translator); m_threadPool.SubmitWork([&, translator, elements = std::move(elements)]() mutable { for (auto const & element : elements) translator->Emit(element); m_translators.Push(translator); }); } bool TranslatorsPool::Finish() { m_threadPool.WaitingStop(); using TranslatorPtr = std::shared_ptr<TranslatorInterface>; threads::ThreadSafeQueue<std::future<TranslatorPtr>> queue; while (!m_translators.Empty()) { std::promise<TranslatorPtr> p; std::shared_ptr<TranslatorInterface> translator; m_translators.TryPop(translator); p.set_value(translator); queue.Push(p.get_future()); } base::ComputationalThreadPool pool(queue.Size() / 2 + 1); CHECK_GREATER_OR_EQUAL(queue.Size(), 1, ()); while (queue.Size() != 1) { std::future<TranslatorPtr> left; std::future<TranslatorPtr> right; queue.WaitAndPop(left); queue.WaitAndPop(right); struct State { std::future<TranslatorPtr> left; std::future<TranslatorPtr> right; }; // Should be copyable to workaround MSVC bug (https://developercommunity.visualstudio.com/t/108672) auto state = std::make_shared<State>(); state->left = std::move(left); state->right = std::move(right); queue.Push(pool.Submit([state = std::move(state)]() mutable { auto leftTranslator = state->left.get(); auto rigthTranslator = state->right.get(); rigthTranslator->Finish(); leftTranslator->Finish(); leftTranslator->Merge(*rigthTranslator); return leftTranslator; })); } std::future<TranslatorPtr> translatorFuture; queue.WaitAndPop(translatorFuture); auto translator = translatorFuture.get(); translator->Finish(); return translator->Save(); } } // namespace generator