diff --git a/include/albatross/Indexing b/include/albatross/Indexing index 9563f424..dbd3f0f9 100644 --- a/include/albatross/Indexing +++ b/include/albatross/Indexing @@ -13,12 +13,14 @@ #ifndef ALBATROSS_INDEXING_H #define ALBATROSS_INDEXING_H +#include #include "Dataset" #include #include #include #include +#include #include #endif diff --git a/include/albatross/src/indexing/async_apply.hpp b/include/albatross/src/indexing/async_apply.hpp new file mode 100644 index 00000000..f3df10b9 --- /dev/null +++ b/include/albatross/src/indexing/async_apply.hpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2020 Swift Navigation Inc. + * Contact: Swift Navigation + * + * This source is subject to the license found in the file 'LICENSE' which must + * be distributed together with this source. All other rights reserved. + * + * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, + * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef INCLUDE_ALBATROSS_SRC_UTILS_ASYNC_UTILS_HPP_ +#define INCLUDE_ALBATROSS_SRC_UTILS_ASYNC_UTILS_HPP_ + +namespace albatross { + +// This method makes sure we don't accidentally call async with the +// default mode which has some flaws: +// +// https://eli.thegreenplace.net/2016/the-promises-and-challenges-of-stdasync-task-based-parallelism-in-c11/ +template +inline auto async_safe(F &&f, Ts &&... params) { + return std::async(std::launch::async, std::forward(f), + std::forward(params)...); +} + +template ::type, + typename std::enable_if::value && + std::is_same::value, + int>::type = 0> +inline void async_apply(const std::vector &xs, ApplyFunction &&f) { + std::vector> futures; + for (const ValueType &x : xs) { + futures.emplace_back(async_safe(f, x)); + } + for (auto &f : futures) { + f.get(); + } +} + +template ::type, + typename std::enable_if::value && + !std::is_same::value, + int>::type = 0> +inline auto async_apply(const std::vector &xs, ApplyFunction &&f) { + std::vector> futures; + for (const ValueType &x : xs) { + futures.emplace_back(async_safe(f, x)); + } + + std::vector output; + for (auto &f : futures) { + output.emplace_back(f.get()); + } + return output; +} + +// Map + +template < + template class Map, typename KeyType, typename ValueType, + typename ApplyFunction, + typename ApplyType = typename details::key_value_apply_result< + ApplyFunction, KeyType, ValueType>::type, + typename std::enable_if::value && + std::is_same::value, + int>::type = 0> +inline void async_apply(const Map &map, ApplyFunction &&f) { + std::vector> futures; + for (const auto &pair : map) { + futures.emplace_back(async_safe(f, pair.first, pair.second)); + } + for (auto &f : futures) { + f.get(); + } +} + +template < + template class Map, typename KeyType, typename ValueType, + typename ApplyFunction, + typename ApplyType = typename details::key_value_apply_result< + ApplyFunction, KeyType, ValueType>::type, + typename std::enable_if::value && + !std::is_same::value, + int>::type = 0> +inline Grouped +async_apply(const Map &map, ApplyFunction &&f) { + + std::map> futures; + for (const auto &pair : map) { + futures[pair.first] = async_safe(f, pair.first, pair.second); + } + + Grouped output; + for (auto &pair : futures) { + output.emplace(pair.first, pair.second.get()); + } + return output; +} + +template