From 0ebf498c42a422d96aac6438dd6904d9cdc96604 Mon Sep 17 00:00:00 2001 From: kleeman Date: Fri, 27 Mar 2020 15:00:33 -0700 Subject: [PATCH 1/4] Add async_apply for map-like objects --- include/albatross/Indexing | 1 + include/albatross/src/indexing/group_by.hpp | 68 ++++++--------- include/albatross/src/utils/async_utils.hpp | 92 ++++++++++++++++++++- tests/test_group_by.cc | 19 ++++- 4 files changed, 132 insertions(+), 48 deletions(-) diff --git a/include/albatross/Indexing b/include/albatross/Indexing index 9563f424..f37c94a3 100644 --- a/include/albatross/Indexing +++ b/include/albatross/Indexing @@ -19,6 +19,7 @@ #include #include #include +#include "./utils/AsyncUtils" #include #endif diff --git a/include/albatross/src/indexing/group_by.hpp b/include/albatross/src/indexing/group_by.hpp index 313b87c0..123345f0 100644 --- a/include/albatross/src/indexing/group_by.hpp +++ b/include/albatross/src/indexing/group_by.hpp @@ -115,6 +115,10 @@ template class GroupedBase { return albatross::apply(map_, std::forward(f)); } + template auto async_apply(ApplyFunction &&f) const { + return albatross::async_apply(map_, std::forward(f)); + } + protected: std::map map_; }; @@ -188,20 +192,13 @@ class Grouped using Base = GroupedBase; using Base::Base; - template ::type, - typename std::enable_if< - details::is_valid_index_apply_function::value && - !std::is_same::value, - int>::type = 0> - auto index_apply(const ApplyFunction &f) const { - Grouped output; - for (const auto &pair : this->map_) { - output.emplace(pair.first, f(pair.first, pair.second)); - } - return output; + template auto index_apply(ApplyFunction &&f) const { + return apply(this->map_, std::forward(f)); + } + + template + auto async_index_apply(ApplyFunction &&f) const { + return async_apply(this->map_, std::forward(f)); } }; @@ -401,8 +398,12 @@ template class GroupByBase { std::size_t size() const { return indexers().size(); } - template auto apply(const ApplyFunction &f) const { - return groups().apply(f); + template auto apply(ApplyFunction &&f) const { + return groups().apply(std::forward(f)); + } + + template auto async_apply(ApplyFunction &&f) const { + return groups().async_apply(std::forward(f)); } ValueType get_group(const KeyType &key) const { @@ -415,38 +416,17 @@ template class GroupByBase { albatross::subset(parent_, first_indexer.second)); } - template ::type, - typename std::enable_if< - details::is_valid_index_apply_function::value && - !std::is_same::value, - int>::type = 0> - auto index_apply(const ApplyFunction &f) const { - Grouped output; - for (const auto &pair : indexers()) { - output.emplace(pair.first, f(pair.first, pair.second)); - } - return output; + template auto index_apply(ApplyFunction &&f) const { + return albatross::apply(indexers(), std::forward(f)); } - template ::type, - typename std::enable_if< - details::is_valid_index_apply_function::value && - std::is_same::value, - int>::type = 0> - void index_apply(const ApplyFunction &f) const { - for (const auto &pair : indexers()) { - f(pair.first, pair.second); - } + template + auto async_index_apply(ApplyFunction &&f) const { + return albatross::async_apply(indexers(), std::forward(f)); } - template auto filter(FilterFunction f) const { - return groups().filter(f); + template auto filter(FilterFunction &&f) const { + return groups().filter(std::forward(f)); } Grouped counts() const { diff --git a/include/albatross/src/utils/async_utils.hpp b/include/albatross/src/utils/async_utils.hpp index 9f2fc40c..4c70b48b 100644 --- a/include/albatross/src/utils/async_utils.hpp +++ b/include/albatross/src/utils/async_utils.hpp @@ -32,7 +32,8 @@ template ::value && std::is_same::value, int>::type = 0> -void async_apply(const std::vector &xs, const ApplyFunction &f) { +inline void async_apply(const std::vector &xs, + ApplyFunction &&f) { std::vector> futures; for (const auto &x : xs) { futures.emplace_back(async_safe(f, x)); @@ -49,7 +50,8 @@ template ::value && !std::is_same::value, int>::type = 0> -auto async_apply(const std::vector &xs, const ApplyFunction &f) { +inline auto async_apply(const std::vector &xs, + ApplyFunction &&f) { std::vector> futures; for (const auto &x : xs) { futures.emplace_back(async_safe(f, x)); @@ -62,6 +64,92 @@ auto async_apply(const std::vector &xs, const ApplyFunction &f) { 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