diff --git a/api/column_family.hh b/api/column_family.hh index 3764b76db7..0d3879fcca 100644 --- a/api/column_family.hh +++ b/api/column_family.hh @@ -58,35 +58,42 @@ future map_reduce_cf(http_context& ctx, const sstring& n }); } -template -future map_reduce_cf_raw(http_context& ctx, const sstring& name, I init, - Mapper mapper, Reducer reducer, Result result) { - auto uuid = get_uuid(name, ctx.db.local()); - return ctx.db.map_reduce0([mapper, uuid](database& db) { - return mapper(db.find_column_family(uuid)); - }, init, reducer); -} - - template future map_reduce_cf(http_context& ctx, const sstring& name, I init, Mapper mapper, Reducer reducer, Result result) { - return map_reduce_cf_raw(ctx, name, init, mapper, reducer, result).then([result](const I& res) mutable { + return map_reduce_cf_raw(ctx, name, init, mapper, reducer).then([result](const I& res) mutable { result = res; return make_ready_future(result); }); } -template -future map_reduce_cf_raw(http_context& ctx, I init, - Mapper mapper, Reducer reducer) { - return ctx.db.map_reduce0([mapper, init, reducer](database& db) { +struct map_reduce_column_families_locally { + std::any init; + std::function mapper; + std::function reducer; + std::any operator()(database& db) const { auto res = init; for (auto i : db.get_column_families()) { res = reducer(res, mapper(*i.second.get())); } return res; - }, init, reducer); + } +}; + +template +future map_reduce_cf_raw(http_context& ctx, I init, + Mapper mapper, Reducer reducer) { + using mapper_type = std::function; + using reducer_type = std::function; + auto wrapped_mapper = mapper_type([mapper = std::move(mapper)] (column_family& cf) mutable { + return I(mapper(cf)); + }); + auto wrapped_reducer = reducer_type([reducer = std::move(reducer)] (std::any a, std::any b) mutable { + return I(reducer(std::any_cast(std::move(a)), std::any_cast(std::move(b)))); + }); + return ctx.db.map_reduce0(map_reduce_column_families_locally{init, std::move(wrapped_mapper), wrapped_reducer}, std::any(init), wrapped_reducer).then([] (std::any res) { + return std::any_cast(std::move(res)); + }); }