Commit 0a2bbe62 authored by Lee Howes's avatar Lee Howes Committed by Facebook Github Bot

add collectAnySemiFuture

Summary: Adds a SemiFuture variant of collectAny and forwards collectAny to it. This ensures that both options are available.

Reviewed By: yfeldblum

Differential Revision: D15111077

fbshipit-source-id: f4d6efc684ca632b71f7a8d2659ca4d968d15b6f
parent 0ad95397
...@@ -1717,6 +1717,14 @@ Future<std::pair< ...@@ -1717,6 +1717,14 @@ Future<std::pair<
size_t, size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>> Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAny(InputIterator first, InputIterator last) { collectAny(InputIterator first, InputIterator last) {
return collectAnySemiFuture(first, last).via(&InlineExecutor::instance());
}
template <class InputIterator>
SemiFuture<std::pair<
size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAnySemiFuture(InputIterator first, InputIterator last) {
using F = typename std::iterator_traits<InputIterator>::value_type; using F = typename std::iterator_traits<InputIterator>::value_type;
using T = typename F::value_type; using T = typename F::value_type;
...@@ -1725,6 +1733,10 @@ collectAny(InputIterator first, InputIterator last) { ...@@ -1725,6 +1733,10 @@ collectAny(InputIterator first, InputIterator last) {
std::atomic<bool> done{false}; std::atomic<bool> done{false};
}; };
std::vector<folly::Executor::KeepAlive<futures::detail::DeferredExecutor>>
executors;
futures::detail::stealDeferredExecutors(executors, first, last);
auto ctx = std::make_shared<Context>(); auto ctx = std::make_shared<Context>();
for (size_t i = 0; first != last; ++first, ++i) { for (size_t i = 0; first != last; ++first, ++i) {
first->setCallback_([i, ctx](Try<T>&& t) { first->setCallback_([i, ctx](Try<T>&& t) {
...@@ -1733,7 +1745,16 @@ collectAny(InputIterator first, InputIterator last) { ...@@ -1733,7 +1745,16 @@ collectAny(InputIterator first, InputIterator last) {
} }
}); });
} }
return ctx->p.getSemiFuture().via(&InlineExecutor::instance()); auto future = ctx->p.getSemiFuture();
if (!executors.empty()) {
future = std::move(future).defer(
[](Try<typename decltype(future)::value_type>&& t) {
return std::move(t).value();
});
auto deferredExecutor = futures::detail::getDeferredExecutor(future);
deferredExecutor->setNestedExecutors(std::move(executors));
}
return future;
} }
// collectAnyWithoutException (iterator) // collectAnyWithoutException (iterator)
......
...@@ -429,6 +429,11 @@ Future<std::pair< ...@@ -429,6 +429,11 @@ Future<std::pair<
size_t, size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>> Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAny(InputIterator first, InputIterator last); collectAny(InputIterator first, InputIterator last);
template <class InputIterator>
SemiFuture<std::pair<
size_t,
Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
collectAnySemiFuture(InputIterator first, InputIterator last);
/// Sugar for the most common case /// Sugar for the most common case
template <class Collection> template <class Collection>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment