Summary:
Oh, this is best of both worlds:
D2015316
If your reduce is really cheap, just use `collect/CollectAll->reduce`.
Otherwise just use `reduce`. Great?
This one doesn't support returning Futures from `func`, but if you want
to do that, just use `reduce`.
Test Plan: Run all the tests.
Reviewed By: hans@fb.com
Subscribers: folly-diffs@, jsedgwick, yfeldblum, chalfant
FB internal diff:
D2017238
Tasks:
6025252
Signature: t1:
2017238:
1430422971:
c3471afa53239681f835624becf3c4a238204b70
return f;
}
+template <class T>
+template <class I, class F>
+Future<I> Future<T>::reduce(I&& initial, F&& func) {
+ folly::MoveWrapper<I> minitial(std::move(initial));
+ folly::MoveWrapper<F> mfunc(std::move(func));
+ return then([minitial, mfunc](T& vals) mutable {
+ auto ret = std::move(*minitial);
+ for (auto& val : vals) {
+ ret = (*mfunc)(std::move(ret), std::move(val));
+ }
+ return ret;
+ });
+}
+
template <class T>
Future<T> Future<T>::within(Duration dur, Timekeeper* tk) {
return within(dur, TimedOut(), tk);
template <class F>
Future<T> filter(F predicate);
+ /// Like reduce, but works on a Future<std::vector<T / Try<T>>>, for example
+ /// the result of collect or collectAll
+ template <class I, class F>
+ Future<I> reduce(I&& initial, F&& func);
+
protected:
typedef detail::Core<T>* corePtr;
}
}
+TEST(Reduce, Chain) {
+ auto makeFutures = [](int count) {
+ std::vector<Future<int>> fs;
+ for (int i = 1; i <= count; ++i) {
+ fs.emplace_back(makeFuture(i));
+ }
+ return fs;
+ };
+
+ {
+ auto f = collectAll(makeFutures(3)).reduce(0, [](int a, Try<int>&& b){
+ return a + *b;
+ });
+ EXPECT_EQ(6, f.get());
+ }
+ {
+ auto f = collect(makeFutures(3)).reduce(0, [](int a, int&& b){
+ return a + b;
+ });
+ EXPECT_EQ(6, f.get());
+ }
+}
+
TEST(Map, Basic) {
Promise<int> p1;
Promise<int> p2;