proxygen
CollectTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <numeric>
18 
19 #include <boost/thread/barrier.hpp>
20 
21 #include <folly/Random.h>
22 #include <folly/futures/Future.h>
24 #include <folly/small_vector.h>
25 
26 using namespace folly;
27 
29 static eggs_t eggs("eggs");
30 
31 auto rng = std::mt19937(folly::randomNumberSeed());
32 
33 TEST(Collect, collectAll) {
34  // returns a vector variant
35  {
36  std::vector<Promise<int>> promises(10);
37  std::vector<Future<int>> futures;
38 
39  for (auto& p : promises) {
40  futures.push_back(p.getFuture());
41  }
42 
43  auto allf = collectAll(futures);
44 
45  std::shuffle(promises.begin(), promises.end(), rng);
46  for (auto& p : promises) {
47  EXPECT_FALSE(allf.isReady());
48  p.setValue(42);
49  }
50 
51  EXPECT_TRUE(allf.isReady());
52  auto& results = allf.value();
53  for (auto& t : results) {
54  EXPECT_EQ(42, t.value());
55  }
56  }
57 
58  // check error semantics
59  {
60  std::vector<Promise<int>> promises(4);
61  std::vector<Future<int>> futures;
62 
63  for (auto& p : promises) {
64  futures.push_back(p.getFuture());
65  }
66 
67  auto allf = collectAll(futures);
68 
69  promises[0].setValue(42);
70  promises[1].setException(eggs);
71 
72  EXPECT_FALSE(allf.isReady());
73 
74  promises[2].setValue(42);
75 
76  EXPECT_FALSE(allf.isReady());
77 
78  promises[3].setException(eggs);
79 
80  EXPECT_TRUE(allf.isReady());
81  EXPECT_FALSE(allf.getTry().hasException());
82 
83  auto& results = allf.value();
84  EXPECT_EQ(42, results[0].value());
85  EXPECT_TRUE(results[1].hasException());
86  EXPECT_EQ(42, results[2].value());
87  EXPECT_TRUE(results[3].hasException());
88  }
89 
90  // check that futures are ready in then()
91  {
92  std::vector<Promise<Unit>> promises(10);
93  std::vector<Future<Unit>> futures;
94 
95  for (auto& p : promises) {
96  futures.push_back(p.getFuture());
97  }
98 
99  auto allf = collectAllSemiFuture(futures).toUnsafeFuture().then(
100  [](Try<std::vector<Try<Unit>>>&& ts) {
101  for (auto& f : ts.value()) {
102  f.value();
103  }
104  });
105 
106  std::shuffle(promises.begin(), promises.end(), rng);
107  for (auto& p : promises) {
108  p.setValue();
109  }
110  EXPECT_TRUE(allf.isReady());
111  }
112 }
113 
114 TEST(Collect, collect) {
115  // success case
116  {
117  std::vector<Promise<int>> promises(10);
118  std::vector<Future<int>> futures;
119 
120  for (auto& p : promises) {
121  futures.push_back(p.getFuture());
122  }
123 
124  auto allf = collect(futures);
125 
126  std::shuffle(promises.begin(), promises.end(), rng);
127  for (auto& p : promises) {
128  EXPECT_FALSE(allf.isReady());
129  p.setValue(42);
130  }
131 
132  EXPECT_TRUE(allf.isReady());
133  for (auto i : allf.value()) {
134  EXPECT_EQ(42, i);
135  }
136  }
137 
138  // failure case
139  {
140  std::vector<Promise<int>> promises(10);
141  std::vector<Future<int>> futures;
142 
143  for (auto& p : promises) {
144  futures.push_back(p.getFuture());
145  }
146 
147  auto allf = collect(futures);
148 
149  std::shuffle(promises.begin(), promises.end(), rng);
150  for (int i = 0; i < 10; i++) {
151  if (i < 5) {
152  // everthing goes well so far...
153  EXPECT_FALSE(allf.isReady());
154  promises[i].setValue(42);
155  } else if (i == 5) {
156  // short circuit with an exception
157  EXPECT_FALSE(allf.isReady());
158  promises[i].setException(eggs);
159  EXPECT_TRUE(allf.isReady());
160  } else if (i < 8) {
161  // don't blow up on further values
162  EXPECT_TRUE(allf.isReady());
163  promises[i].setValue(42);
164  } else {
165  // don't blow up on further exceptions
166  EXPECT_TRUE(allf.isReady());
167  promises[i].setException(eggs);
168  }
169  }
170 
171  EXPECT_THROW(allf.value(), eggs_t);
172  }
173 
174  // void futures success case
175  {
176  std::vector<Promise<Unit>> promises(10);
177  std::vector<Future<Unit>> futures;
178 
179  for (auto& p : promises) {
180  futures.push_back(p.getFuture());
181  }
182 
183  auto allf = collect(futures);
184 
185  std::shuffle(promises.begin(), promises.end(), rng);
186  for (auto& p : promises) {
187  EXPECT_FALSE(allf.isReady());
188  p.setValue();
189  }
190 
191  EXPECT_TRUE(allf.isReady());
192  }
193 
194  // void futures failure case
195  {
196  std::vector<Promise<Unit>> promises(10);
197  std::vector<Future<Unit>> futures;
198 
199  for (auto& p : promises) {
200  futures.push_back(p.getFuture());
201  }
202 
203  auto allf = collect(futures);
204 
205  std::shuffle(promises.begin(), promises.end(), rng);
206  for (int i = 0; i < 10; i++) {
207  if (i < 5) {
208  // everthing goes well so far...
209  EXPECT_FALSE(allf.isReady());
210  promises[i].setValue();
211  } else if (i == 5) {
212  // short circuit with an exception
213  EXPECT_FALSE(allf.isReady());
214  promises[i].setException(eggs);
215  EXPECT_TRUE(allf.isReady());
216  } else if (i < 8) {
217  // don't blow up on further values
218  EXPECT_TRUE(allf.isReady());
219  promises[i].setValue();
220  } else {
221  // don't blow up on further exceptions
222  EXPECT_TRUE(allf.isReady());
223  promises[i].setException(eggs);
224  }
225  }
226 
227  EXPECT_THROW(allf.value(), eggs_t);
228  }
229 
230  // move only compiles
231  {
232  std::vector<Promise<std::unique_ptr<int>>> promises(10);
233  std::vector<Future<std::unique_ptr<int>>> futures;
234 
235  for (auto& p : promises) {
236  futures.push_back(p.getFuture());
237  }
238 
239  collect(futures);
240  }
241 }
242 
244  NotDefaultConstructible() = delete;
245  explicit NotDefaultConstructible(int arg) : i(arg) {}
246  int i;
247 };
248 
249 // We have a specialized implementation for non-default-constructible objects
250 // Ensure that it works and preserves order
251 TEST(Collect, collectNotDefaultConstructible) {
252  std::vector<Promise<NotDefaultConstructible>> promises(10);
253  std::vector<Future<NotDefaultConstructible>> futures;
254  std::vector<int> indices(10);
255  std::iota(indices.begin(), indices.end(), 0);
256  std::shuffle(indices.begin(), indices.end(), rng);
257 
258  for (auto& p : promises) {
259  futures.push_back(p.getFuture());
260  }
261 
262  auto allf = collect(futures);
263 
264  for (auto i : indices) {
265  EXPECT_FALSE(allf.isReady());
266  promises[i].setValue(NotDefaultConstructible(i));
267  }
268 
269  EXPECT_TRUE(allf.isReady());
270  int i = 0;
271  for (auto val : allf.value()) {
272  EXPECT_EQ(i, val.i);
273  i++;
274  }
275 }
276 
277 TEST(Collect, collectAny) {
278  {
279  std::vector<Promise<int>> promises(10);
280  std::vector<Future<int>> futures;
281 
282  for (auto& p : promises) {
283  futures.push_back(p.getFuture());
284  }
285 
286  for (auto& f : futures) {
287  EXPECT_FALSE(f.isReady());
288  }
289 
290  auto anyf = collectAny(futures);
291 
292  /* futures were moved in, so these are invalid now */
293  EXPECT_FALSE(anyf.isReady());
294 
295  promises[7].setValue(42);
296  EXPECT_TRUE(anyf.isReady());
297  auto& idx_fut = anyf.value();
298 
299  auto i = idx_fut.first;
300  EXPECT_EQ(7, i);
301 
302  auto& f = idx_fut.second;
303  EXPECT_EQ(42, f.value());
304  }
305 
306  // error
307  {
308  std::vector<Promise<Unit>> promises(10);
309  std::vector<Future<Unit>> futures;
310 
311  for (auto& p : promises) {
312  futures.push_back(p.getFuture());
313  }
314 
315  for (auto& f : futures) {
316  EXPECT_FALSE(f.isReady());
317  }
318 
319  auto anyf = collectAny(futures);
320 
321  EXPECT_FALSE(anyf.isReady());
322 
323  promises[3].setException(eggs);
324  EXPECT_TRUE(anyf.isReady());
325  EXPECT_TRUE(anyf.value().second.hasException());
326  }
327 
328  // then()
329  {
330  std::vector<Promise<int>> promises(10);
331  std::vector<Future<int>> futures;
332 
333  for (auto& p : promises) {
334  futures.push_back(p.getFuture());
335  }
336 
337  auto anyf = collectAny(futures).then(
338  [](std::pair<size_t, Try<int>> p) { EXPECT_EQ(42, p.second.value()); });
339 
340  promises[3].setValue(42);
341  EXPECT_TRUE(anyf.isReady());
342  }
343 }
344 
347 
348  {
349  std::vector<Promise<int>> promises(10);
350  std::vector<Future<int>> futures;
351 
352  for (auto& p : promises) {
353  futures.push_back(p.getFuture());
354  }
355 
356  auto onef = collectAnyWithoutException(futures).via(&executor);
357 
358  /* futures were moved in, so these are invalid now */
359  EXPECT_FALSE(onef.isReady());
360 
361  promises[7].setValue(42);
362  EXPECT_TRUE(onef.isReady());
363  auto& idx_fut = onef.value();
364  EXPECT_EQ(7, idx_fut.first);
365  EXPECT_EQ(42, idx_fut.second);
366  }
367 
368  // some exception before ready
369  {
370  std::vector<Promise<int>> promises(10);
371  std::vector<Future<int>> futures;
372 
373  for (auto& p : promises) {
374  futures.push_back(p.getFuture());
375  }
376 
377  auto onef = collectAnyWithoutException(futures).via(&executor);
378 
379  EXPECT_FALSE(onef.isReady());
380 
381  promises[3].setException(eggs);
382  EXPECT_FALSE(onef.isReady());
383  promises[4].setException(eggs);
384  EXPECT_FALSE(onef.isReady());
385  promises[0].setValue(99);
386  EXPECT_TRUE(onef.isReady());
387  auto& idx_fut = onef.value();
388  EXPECT_EQ(0, idx_fut.first);
389  EXPECT_EQ(99, idx_fut.second);
390  }
391 
392  // all exceptions
393  {
394  std::vector<Promise<int>> promises(10);
395  std::vector<Future<int>> futures;
396 
397  for (auto& p : promises) {
398  futures.push_back(p.getFuture());
399  }
400 
401  auto onef = collectAnyWithoutException(futures).via(&executor);
402 
403  EXPECT_FALSE(onef.isReady());
404  for (int i = 0; i < 9; ++i) {
405  promises[i].setException(eggs);
406  }
407  EXPECT_FALSE(onef.isReady());
408 
409  promises[9].setException(eggs);
410  EXPECT_TRUE(onef.isReady());
411  EXPECT_TRUE(onef.hasException());
412  }
413 
414  // Deferred work
415  {
416  std::vector<Promise<int>> promises(10);
417 
418  auto onef = [&] {
419  std::vector<SemiFuture<int>> futures;
420 
421  for (auto& p : promises) {
422  futures.push_back(
423  p.getSemiFuture().deferValue([](auto v) { return v; }));
424  }
425  return collectAnyWithoutException(futures);
426  }();
427 
428  /* futures were moved in, so these are invalid now */
429 
430  promises[7].setValue(42);
431  auto idx_fut = std::move(onef).get();
432  EXPECT_EQ(7, idx_fut.first);
433  EXPECT_EQ(42, idx_fut.second);
434  }
435 }
436 
437 TEST(Collect, alreadyCompleted) {
438  {
439  std::vector<Future<Unit>> fs;
440  for (int i = 0; i < 10; i++) {
441  fs.push_back(makeFuture());
442  }
443 
444  collectAllSemiFuture(fs).toUnsafeFuture().then(
445  [&](std::vector<Try<Unit>> ts) { EXPECT_EQ(fs.size(), ts.size()); });
446  }
447  {
448  std::vector<Future<int>> fs;
449  for (int i = 0; i < 10; i++) {
450  fs.push_back(makeFuture(i));
451  }
452 
453  collectAny(fs).then([&](std::pair<size_t, Try<int>> p) {
454  EXPECT_EQ(p.first, p.second.value());
455  });
456  }
457 }
458 
459 TEST(Collect, parallel) {
460  std::vector<Promise<int>> ps(10);
461  std::vector<Future<int>> fs;
462  for (size_t i = 0; i < ps.size(); i++) {
463  fs.emplace_back(ps[i].getFuture());
464  }
465  auto f = collect(fs);
466 
467  std::vector<std::thread> ts;
468  boost::barrier barrier(ps.size() + 1);
469  for (size_t i = 0; i < ps.size(); i++) {
470  ts.emplace_back([&ps, &barrier, i]() {
471  barrier.wait();
472  ps[i].setValue(i);
473  });
474  }
475 
476  barrier.wait();
477 
478  for (size_t i = 0; i < ps.size(); i++) {
479  ts[i].join();
480  }
481 
482  EXPECT_TRUE(f.isReady());
483  for (size_t i = 0; i < ps.size(); i++) {
484  EXPECT_EQ(i, f.value()[i]);
485  }
486 }
487 
488 TEST(Collect, parallelWithError) {
489  std::vector<Promise<int>> ps(10);
490  std::vector<Future<int>> fs;
491  for (size_t i = 0; i < ps.size(); i++) {
492  fs.emplace_back(ps[i].getFuture());
493  }
494  auto f = collect(fs);
495 
496  std::vector<std::thread> ts;
497  boost::barrier barrier(ps.size() + 1);
498  for (size_t i = 0; i < ps.size(); i++) {
499  ts.emplace_back([&ps, &barrier, i]() {
500  barrier.wait();
501  if (i == (ps.size() / 2)) {
502  ps[i].setException(eggs);
503  } else {
504  ps[i].setValue(i);
505  }
506  });
507  }
508 
509  barrier.wait();
510 
511  for (size_t i = 0; i < ps.size(); i++) {
512  ts[i].join();
513  }
514 
515  EXPECT_TRUE(f.isReady());
516  EXPECT_THROW(f.value(), eggs_t);
517 }
518 
519 TEST(Collect, allParallel) {
520  std::vector<Promise<int>> ps(10);
521  std::vector<Future<int>> fs;
522  for (size_t i = 0; i < ps.size(); i++) {
523  fs.emplace_back(ps[i].getFuture());
524  }
525  auto f = collectAll(fs);
526 
527  std::vector<std::thread> ts;
528  boost::barrier barrier(ps.size() + 1);
529  for (size_t i = 0; i < ps.size(); i++) {
530  ts.emplace_back([&ps, &barrier, i]() {
531  barrier.wait();
532  ps[i].setValue(i);
533  });
534  }
535 
536  barrier.wait();
537 
538  for (size_t i = 0; i < ps.size(); i++) {
539  ts[i].join();
540  }
541 
542  EXPECT_TRUE(f.isReady());
543  for (size_t i = 0; i < ps.size(); i++) {
544  EXPECT_TRUE(f.value()[i].hasValue());
545  EXPECT_EQ(i, f.value()[i].value());
546  }
547 }
548 
549 TEST(Collect, allParallelWithError) {
550  std::vector<Promise<int>> ps(10);
551  std::vector<Future<int>> fs;
552  for (size_t i = 0; i < ps.size(); i++) {
553  fs.emplace_back(ps[i].getFuture());
554  }
555  auto f = collectAll(fs);
556 
557  std::vector<std::thread> ts;
558  boost::barrier barrier(ps.size() + 1);
559  for (size_t i = 0; i < ps.size(); i++) {
560  ts.emplace_back([&ps, &barrier, i]() {
561  barrier.wait();
562  if (i == (ps.size() / 2)) {
563  ps[i].setException(eggs);
564  } else {
565  ps[i].setValue(i);
566  }
567  });
568  }
569 
570  barrier.wait();
571 
572  for (size_t i = 0; i < ps.size(); i++) {
573  ts[i].join();
574  }
575 
576  EXPECT_TRUE(f.isReady());
577  for (size_t i = 0; i < ps.size(); i++) {
578  if (i == (ps.size() / 2)) {
579  EXPECT_THROW(f.value()[i].value(), eggs_t);
580  } else {
581  EXPECT_TRUE(f.value()[i].hasValue());
582  EXPECT_EQ(i, f.value()[i].value());
583  }
584  }
585 }
586 
587 TEST(Collect, collectN) {
588  std::vector<Promise<Unit>> promises(10);
589  std::vector<Future<Unit>> futures;
590 
591  for (auto& p : promises) {
592  futures.push_back(p.getFuture());
593  }
594 
595  bool flag = false;
596  size_t n = 3;
597  collectN(futures, n)
598  .via(&InlineExecutor::instance())
599  .then([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
600  flag = true;
601  EXPECT_EQ(n, v.size());
602  for (auto& tt : v) {
603  EXPECT_TRUE(tt.second.hasValue());
604  }
605  });
606 
607  promises[0].setValue();
608  EXPECT_FALSE(flag);
609  promises[1].setValue();
610  EXPECT_FALSE(flag);
611  promises[2].setValue();
612  EXPECT_TRUE(flag);
613 }
614 
615 TEST(Collect, collectNParallel) {
616  std::vector<Promise<Unit>> ps(100);
617  std::vector<Future<Unit>> futures;
618 
619  for (auto& p : ps) {
620  futures.push_back(p.getFuture());
621  }
622 
623  bool flag = false;
624  size_t n = 90;
625  collectN(futures, n)
626  .via(&InlineExecutor::instance())
627  .then([&](std::vector<std::pair<size_t, Try<Unit>>> v) {
628  flag = true;
629  EXPECT_EQ(n, v.size());
630  for (auto& tt : v) {
631  EXPECT_TRUE(tt.second.hasValue());
632  }
633  });
634 
635  std::vector<std::thread> ts;
636  boost::barrier barrier(ps.size() + 1);
637  for (size_t i = 0; i < ps.size(); i++) {
638  ts.emplace_back([&ps, &barrier, i]() {
639  barrier.wait();
640  ps[i].setValue();
641  });
642  }
643 
644  barrier.wait();
645 
646  for (size_t i = 0; i < ps.size(); i++) {
647  ts[i].join();
648  }
649 
650  EXPECT_TRUE(flag);
651 }
652 
654 TEST(Collect, smallVector) {
655  static_assert(
657  "Futures should not be trivially copyable");
658  static_assert(
660  "Futures should not be trivially copyable");
661 
662  {
664 
665  for (int i = 0; i < 10; i++) {
666  futures.push_back(makeFuture());
667  }
668 
669  auto anyf = collectAny(futures);
670  }
671  {
673 
674  for (int i = 0; i < 10; i++) {
675  futures.push_back(makeFuture());
676  }
677 
678  auto allf = collectAll(futures);
679  }
680 }
681 
682 TEST(Collect, collectAllVariadic) {
683  Promise<bool> pb;
684  Promise<int> pi;
685  Future<bool> fb = pb.getFuture();
686  Future<int> fi = pi.getFuture();
687  bool flag = false;
689  .toUnsafeFuture()
690  .then([&](std::tuple<Try<bool>, Try<int>> tup) {
691  flag = true;
692  EXPECT_TRUE(std::get<0>(tup).hasValue());
693  EXPECT_EQ(std::get<0>(tup).value(), true);
694  EXPECT_TRUE(std::get<1>(tup).hasValue());
695  EXPECT_EQ(std::get<1>(tup).value(), 42);
696  });
697  pb.setValue(true);
698  EXPECT_FALSE(flag);
699  pi.setValue(42);
700  EXPECT_TRUE(flag);
701 }
702 
703 TEST(Collect, collectAllVariadicReferences) {
704  Promise<bool> pb;
705  Promise<int> pi;
706  Future<bool> fb = pb.getFuture();
707  Future<int> fi = pi.getFuture();
708  bool flag = false;
709  collectAllSemiFuture(fb, fi).toUnsafeFuture().then(
710  [&](std::tuple<Try<bool>, Try<int>> tup) {
711  flag = true;
712  EXPECT_TRUE(std::get<0>(tup).hasValue());
713  EXPECT_EQ(std::get<0>(tup).value(), true);
714  EXPECT_TRUE(std::get<1>(tup).hasValue());
715  EXPECT_EQ(std::get<1>(tup).value(), 42);
716  });
717  pb.setValue(true);
718  EXPECT_FALSE(flag);
719  pi.setValue(42);
720  EXPECT_TRUE(flag);
721 }
722 
723 TEST(Collect, collectAllVariadicWithException) {
724  Promise<bool> pb;
725  Promise<int> pi;
726  Future<bool> fb = pb.getFuture();
727  Future<int> fi = pi.getFuture();
728  bool flag = false;
730  .toUnsafeFuture()
731  .then([&](std::tuple<Try<bool>, Try<int>> tup) {
732  flag = true;
733  EXPECT_TRUE(std::get<0>(tup).hasValue());
734  EXPECT_EQ(std::get<0>(tup).value(), true);
735  EXPECT_TRUE(std::get<1>(tup).hasException());
736  EXPECT_THROW(std::get<1>(tup).value(), eggs_t);
737  });
738  pb.setValue(true);
739  EXPECT_FALSE(flag);
740  pi.setException(eggs);
741  EXPECT_TRUE(flag);
742 }
743 
744 TEST(Collect, collectVariadic) {
745  Promise<bool> pb;
746  Promise<int> pi;
747  Future<bool> fb = pb.getFuture();
748  Future<int> fi = pi.getFuture();
749  bool flag = false;
750  collect(std::move(fb), std::move(fi)).then([&](std::tuple<bool, int> tup) {
751  flag = true;
752  EXPECT_EQ(std::get<0>(tup), true);
753  EXPECT_EQ(std::get<1>(tup), 42);
754  });
755  pb.setValue(true);
756  EXPECT_FALSE(flag);
757  pi.setValue(42);
758  EXPECT_TRUE(flag);
759 }
760 
761 TEST(Collect, collectVariadicWithException) {
762  Promise<bool> pb;
763  Promise<int> pi;
764  Future<bool> fb = pb.getFuture();
765  Future<int> fi = pi.getFuture();
766  auto f = collect(std::move(fb), std::move(fi));
767  pb.setValue(true);
768  EXPECT_FALSE(f.isReady());
769  pi.setException(eggs);
770  EXPECT_TRUE(f.isReady());
771  EXPECT_TRUE(f.getTry().hasException());
772  EXPECT_THROW(std::move(f).get(), eggs_t);
773 }
774 
775 TEST(Collect, collectAllNone) {
776  std::vector<Future<int>> fs;
777  auto f = collectAll(fs);
778  EXPECT_TRUE(f.isReady());
779 }
780 
781 TEST(Collect, noDefaultConstructor) {
782  struct A {
783  explicit A(size_t /* x */) {}
784  };
785 
786  auto f1 = makeFuture(A(1));
787  auto f2 = makeFuture(A(2));
788 
789  auto f = collect(std::move(f1), std::move(f2));
790 }
auto f
auto v
std::unique_ptr< int > A
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
double val
Definition: String.cpp:273
void setException(exception_wrapper ew)
Definition: Promise-inl.h:111
SemiFuture< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAllSemiFuture(Fs &&...fs)
Definition: Future-inl.h:1441
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static once_flag flag
Definition: Random.cpp:75
SemiFuture< std::vector< std::pair< size_t, Try< typename std::iterator_traits< InputIterator >::value_type::value_type > > > > collectN(InputIterator first, InputIterator last, size_t n)
Definition: Future-inl.h:1692
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
auto rng
Definition: CollectTest.cpp:31
SemiFuture< std::pair< size_t, typename std::iterator_traits< InputIterator >::value_type::value_type > > collectAnyWithoutException(InputIterator first, InputIterator last)
Definition: Future-inl.h:1644
void push_back(value_type &&t)
Definition: small_vector.h:757
Future< std::pair< size_t, Try< typename std::iterator_traits< InputIterator >::value_type::value_type > > > collectAny(InputIterator first, InputIterator last)
Definition: Future-inl.h:1618
FOLLY_ATTR_VISIBILITY_HIDDEN static FOLLY_ALWAYS_INLINE InlineExecutor & instance() noexcept
Future< T > getFuture()
Definition: Promise-inl.h:97
Future< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAll(Fs &&...fs)
Definition: Future-inl.h:1477
Parallel parallel(Ops ops, size_t threads=0)
Definition: Parallel.h:88
std::is_trivially_copyable< T > is_trivially_copyable
Definition: Traits.h:313
FutureException eggs_t
Definition: CollectTest.cpp:28
Definition: Try.h:51
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
Definition: Promise.h:326
Future< std::vector< typename std::iterator_traits< InputIterator >::value_type::value_type > > collect(InputIterator first, InputIterator last)
Definition: Future-inl.h:1536
static eggs_t eggs("eggs")
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
uint32_t randomNumberSeed()
Definition: Random.h:367
TEST(SequencedExecutor, CPUThreadPoolExecutor)
Future< typename std::decay< T >::type > makeFuture(T &&t)
Definition: Future-inl.h:1310