cache_hitrate_calculator: do not copy stats map for each cpu

invoke_on_all() copies provided function for each shard it is executed
on, so by moving stats map into the capture we copy it for each shard
too. Avoid it by putting it into the top level object which is already
captured by reference.
Message-Id: <20190516132748.6469-2-gleb@scylladb.com>

(cherry picked from commit 4517c56a57)
This commit is contained in:
Gleb Natapov
2019-05-16 16:27:47 +03:00
committed by Tomasz Grabiec
parent b6307d54be
commit 1bb84cdbcf
2 changed files with 16 additions and 13 deletions

View File

@@ -28,11 +28,22 @@
namespace service {
class cache_hitrate_calculator : public seastar::async_sharded_service<cache_hitrate_calculator> {
struct stat {
float h = 0;
float m = 0;
stat& operator+=(stat& o) {
h += o.h;
m += o.m;
return *this;
}
};
seastar::sharded<database>& _db;
seastar::sharded<cache_hitrate_calculator>& _me;
timer<lowres_clock> _timer;
bool _stopped = false;
float _diff = 0;
std::unordered_map<utils::UUID, stat> _rates;
future<> _done = make_ready_future();
future<lowres_clock::duration> recalculate_hitrates();

View File

@@ -112,16 +112,6 @@ void cache_hitrate_calculator::run_on(size_t master, lowres_clock::duration d) {
}
future<lowres_clock::duration> cache_hitrate_calculator::recalculate_hitrates() {
struct stat {
float h = 0;
float m = 0;
stat& operator+=(stat& o) {
h += o.h;
m += o.m;
return *this;
}
};
auto non_system_filter = [&] (const std::pair<utils::UUID, lw_shared_ptr<column_family>>& cf) {
return _db.local().find_keyspace(cf.second->schema()->ks_name()).get_replication_strategy().get_type() != locator::replication_strategy_type::local;
};
@@ -143,12 +133,13 @@ future<lowres_clock::duration> cache_hitrate_calculator::recalculate_hitrates()
return _db.map_reduce0(cf_to_cache_hit_stats, std::unordered_map<utils::UUID, stat>(), sum_stats_per_cf).then([this, non_system_filter] (std::unordered_map<utils::UUID, stat> rates) mutable {
_diff = 0;
_rates = std::move(rates);
// set calculated rates on all shards
return _db.invoke_on_all([this, rates = std::move(rates), cpuid = engine().cpu_id(), non_system_filter] (database& db) {
return _db.invoke_on_all([this, cpuid = engine().cpu_id(), non_system_filter] (database& db) {
sstring gstate;
for (auto& cf : db.get_column_families() | boost::adaptors::filtered(non_system_filter)) {
auto it = rates.find(cf.first);
if (it == rates.end()) { // a table may be added before map/reduce compltes and this code runs
auto it = _rates.find(cf.first);
if (it == _rates.end()) { // a table may be added before map/reduce completes and this code runs
continue;
}
stat s = it->second;
@@ -171,6 +162,7 @@ future<lowres_clock::duration> cache_hitrate_calculator::recalculate_hitrates()
return make_ready_future<>();
});
}).then([this] {
_rates.clear();
// if max difference during this round is big schedule next recalculate earlier
if (_diff < 0.01) {
return std::chrono::milliseconds(2000);