Skip to content

Commit a91f5c9

Browse files
committed
Merge branch 'feature/parallelize-routing'
2 parents ee6b55a + 172adcb commit a91f5c9

3 files changed

Lines changed: 40 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- Remove `LOG_LS_OPERATORS` (#1263)
3333
- Update README to clarify high-level purpose and usage of the project (#1264)
3434
- Remove unused breaks_travel_margin members from TWRoute and associated code (#1295)
35+
- Run routing requests in parallel (#1218)
3536

3637
#### CI
3738

src/structures/typedefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ constexpr unsigned MAX_EXPLORATION_LEVEL = 5;
8282

8383
constexpr unsigned DEFAULT_EXPLORATION_LEVEL = 5;
8484
constexpr unsigned DEFAULT_THREADS_NUMBER = 4;
85+
constexpr unsigned MAX_ROUTING_THREADS = 32;
8586

8687
constexpr auto DEFAULT_MAX_TASKS = std::numeric_limits<size_t>::max();
8788
constexpr auto DEFAULT_MAX_TRAVEL_TIME = std::numeric_limits<Duration>::max();

src/structures/vroom/input/input.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ All rights reserved (see LICENSE).
99

1010
#include <algorithm>
1111
#include <mutex>
12+
#include <semaphore>
1213
#include <thread>
1314

1415
#if USE_LIBOSRM
@@ -1248,16 +1249,44 @@ Solution Input::solve(const unsigned nb_searches,
12481249
.count();
12491250

12501251
if (_geometry) {
1251-
for (auto& route : sol.routes) {
1252-
const auto& profile = route.profile;
1253-
auto rw = std::ranges::find_if(_routing_wrappers, [&](const auto& wr) {
1254-
return wr->profile == profile;
1255-
});
1256-
if (rw == _routing_wrappers.end()) {
1257-
throw InputException(
1258-
"Route geometry request with non-routable profile " + profile + ".");
1252+
std::vector<std::jthread> threads;
1253+
threads.reserve(sol.routes.size());
1254+
std::exception_ptr ep = nullptr;
1255+
std::mutex ep_m;
1256+
std::counting_semaphore<MAX_ROUTING_THREADS> semaphore(
1257+
std::min(MAX_ROUTING_THREADS, nb_thread));
1258+
1259+
auto run_routing = [this, &semaphore, &sol, &ep, &ep_m](std::size_t i) {
1260+
semaphore.acquire();
1261+
try {
1262+
auto& route = sol.routes[i];
1263+
const auto& profile = route.profile;
1264+
auto rw = std::ranges::find_if(_routing_wrappers, [&](const auto& wr) {
1265+
return wr->profile == profile;
1266+
});
1267+
if (rw == _routing_wrappers.end()) {
1268+
throw InputException(
1269+
"Route geometry request with non-routable profile " + profile +
1270+
".");
1271+
}
1272+
(*rw)->add_geometry(route);
1273+
} catch (...) {
1274+
const std::scoped_lock<std::mutex> lock(ep_m);
1275+
ep = std::current_exception();
12591276
}
1260-
(*rw)->add_geometry(route);
1277+
semaphore.release();
1278+
};
1279+
1280+
for (std::size_t i = 0; i < sol.routes.size(); ++i) {
1281+
threads.emplace_back(run_routing, i);
1282+
}
1283+
1284+
for (auto& t : threads) {
1285+
t.join();
1286+
}
1287+
1288+
if (ep != nullptr) {
1289+
std::rethrow_exception(ep);
12611290
}
12621291

12631292
_end_routing = std::chrono::high_resolution_clock::now();

0 commit comments

Comments
 (0)