/*
* 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"
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;
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 = 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
*/
struct ratio_holder : public json::jsonable {
double total = 0;
double sub = 0;
virtual std::string to_json() const {
if (total == 0) {
return "0";
}
return std::to_string(sub/total);
}
ratio_holder() = default;
ratio_holder& add(double _total, double _sub) {
total += _total;
sub += _sub;
return *this;
}
ratio_holder(double _total, double _sub) {
total = _total;
sub = _sub;
}
ratio_holder& operator+=(const ratio_holder& a) {
return add(a.total, a.sub);
}
friend ratio_holder operator+(ratio_holder a, const ratio_holder& b) {
return a += b;
}
};
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;
}
}