From 362ab5b7cee523d638a360b94dfe8c1e0856f850 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Thu, 17 Oct 2019 17:45:22 +0200 Subject: [PATCH] crimson: avoid plainifying/errorating in crimson::for_for_each(). We don't want to convert between `errorator::future` and `seastar::future` back and forth due to performance penalty. Signed-off-by: Radoslaw Zarzynski --- src/crimson/common/errorator.h | 59 +++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 93995b98022..b798f7408b9 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -8,18 +8,39 @@ namespace crimson { -template -static inline auto do_for_each(Container& c, AsyncAction action) { - using ActionItem = typename Container::value_type; - using ActionReturn = std::invoke_result_t; - using Errorator = typename ActionReturn::errorator_type; - using Futurator = typename Errorator::template futurize; - return typename Futurator::type { - seastar::do_for_each(std::begin(c), std::end(c), - [action = std::move(action)] (auto& item) -> seastar::future<> { - return Errorator::plainify(action(item)); - }) - }; +template +inline auto do_for_each(Iterator begin, Iterator end, AsyncAction action) { + using futurator = \ + ::seastar::futurize>; + + if (begin == end) { + return futurator::type::errorator_type::template make_ready_future<>(); + } + while (true) { + auto f = futurator::apply(action, *begin); + ++begin; + if (begin == end) { + return f; + } + if (!f.available() || seastar::need_preempt()) { + return std::move(f)._then( + [ action = std::move(action), + begin = std::move(begin), + end = std::move(end) + ] () mutable { + return ::crimson::do_for_each(std::move(begin), + std::move(end), + std::move(action)); + }); + } + if (f.failed()) { + return f; + } + } +} +template +inline auto do_for_each(Container& c, AsyncAction action) { + return ::crimson::do_for_each(std::begin(c), std::end(c), std::move(action)); } template @@ -463,8 +484,17 @@ struct errorator { template void then(Func&&) = delete; - private: + // for ::crimson::do_for_each + template + auto _then(Func&& func) { + return base_t::then(std::forward(func)); + } + template + friend inline auto ::crimson::do_for_each(Iterator begin, + Iterator end, + AsyncAction action); + // for the sake of `plainify()` let any errorator convert errorated // future into plain one. template @@ -642,9 +672,6 @@ private: template friend class future; - template - friend inline auto ::crimson::do_for_each(Container&, AsyncAction); - template friend inline auto do_with(T&&, F&&); }; // class errorator, generic template -- 2.39.5