/* * Copyright 2015 ScyllaDB */ /* * This file is part of Scylla. * * Scylla is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Scylla is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Scylla. If not, see . */ #pragma once #include "json/json_elements.hh" #include #include #include #include "api/api-doc/utils.json.hh" #include "utils/histogram.hh" #include "http/exception.hh" #include "api_init.hh" #include "seastarx.hh" namespace api { template std::vector container_to_vec(const T& container) { std::vector res; for (auto i : container) { res.push_back(boost::lexical_cast(i)); } return res; } template std::vector map_to_key_value(const std::map& map) { std::vector res; for (auto i : map) { res.push_back(T()); res.back().key = i.first; res.back().value = i.second; } return res; } template std::vector& map_to_key_value(const MAP& map, std::vector& res) { for (auto i : map) { T val; val.key = boost::lexical_cast(i.first); val.value = boost::lexical_cast(i.second); res.push_back(val); } return res; } template T map_sum(T&& dest, const S& src) { for (auto i : src) { dest[i.first] += i.second; } return dest; } template std::vector map_keys(const MAP& map) { std::vector res; for (const auto& i : map) { res.push_back(boost::lexical_cast(i.first)); } return res; } /** * General sstring splitting function */ inline std::vector split(const sstring& text, const char* separator) { if (text == "") { return std::vector(); } std::vector tokens; return boost::split(tokens, text, boost::is_any_of(separator)); } /** * Split a column family parameter */ inline std::vector split_cf(const sstring& cf) { return split(cf, ","); } /** * A helper function to sum values on an a distributed object that * has a get_stats method. * */ template future sum_stats(distributed& d, V F::*f) { return d.map_reduce0([f](const T& p) {return p.get_stats().*f;}, 0, std::plus()).then([](V val) { return make_ready_future(val); }); } inline httpd::utils_json::histogram to_json(const utils::ihistogram& val) { httpd::utils_json::histogram h; h = val; h.sum = val.estimated_sum(); return h; } inline httpd::utils_json::rate_moving_average meter_to_json(const utils::rate_moving_average& val) { httpd::utils_json::rate_moving_average m; m = val; return m; } inline httpd::utils_json::rate_moving_average_and_histogram timer_to_json(const utils::rate_moving_average_and_histogram& val) { httpd::utils_json::rate_moving_average_and_histogram h; h.hist = to_json(val.hist); h.meter = meter_to_json(val.rate); return h; } template future sum_histogram_stats(distributed& d, utils::timed_rate_moving_average_and_histogram F::*f) { return d.map_reduce0([f](const T& p) {return (p.get_stats().*f).hist;}, utils::ihistogram(), std::plus()).then([](const utils::ihistogram& val) { return make_ready_future(to_json(val)); }); } template future sum_timer_stats(distributed& d, utils::timed_rate_moving_average_and_histogram F::*f) { return d.map_reduce0([f](const T& p) {return (p.get_stats().*f).rate();}, utils::rate_moving_average_and_histogram(), std::plus()).then([](const utils::rate_moving_average_and_histogram& val) { return make_ready_future(timer_to_json(val)); }); } inline int64_t min_int64(int64_t a, int64_t b) { return std::min(a,b); } inline int64_t max_int64(int64_t a, int64_t b) { return std::max(a,b); } /** * A helper struct for ratio calculation * It combine total and the sub set for the ratio and its * to_json method return the ration sub/total */ template struct basic_ratio_holder : public json::jsonable { T total = 0; T sub = 0; virtual std::string to_json() const { if (total == 0) { return "0"; } return std::to_string(sub/total); } basic_ratio_holder() = default; basic_ratio_holder& add(T _total, T _sub) { total += _total; sub += _sub; return *this; } basic_ratio_holder(T _total, T _sub) { total = _total; sub = _sub; } basic_ratio_holder& operator+=(const basic_ratio_holder& a) { return add(a.total, a.sub); } friend basic_ratio_holder operator+(basic_ratio_holder a, const basic_ratio_holder& b) { return a += b; } }; typedef basic_ratio_holder ratio_holder; typedef basic_ratio_holder integral_ratio_holder; class unimplemented_exception : public base_exception { public: unimplemented_exception() : base_exception("API call is not supported yet", reply::status_type::internal_server_error) { } }; inline void unimplemented() { throw unimplemented_exception(); } template std::vector concat(std::vector a, std::vector&& b) { a.reserve( a.size() + b.size()); a.insert(a.end(), b.begin(), b.end()); return a; } }