1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
/*
* This file is part of PowerDNS or dnsdist.
* Copyright -- PowerDNS.COM B.V. and its contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* In addition, for the avoidance of any doubt, permission is granted to
* link this program with OpenSSL and to (re)distribute the binaries
* produced as the result of such linking.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dnsdist-rings.hh"
size_t Rings::numDistinctRequestors()
{
std::set<ComboAddress, ComboAddress::addressOnlyLessThan> s;
for (const auto& shard : d_shards) {
std::lock_guard<std::mutex> rl(shard->queryLock);
for(const auto& q : shard->queryRing) {
s.insert(q.requestor);
}
}
return s.size();
}
std::unordered_map<int, vector<boost::variant<string,double>>> Rings::getTopBandwidth(unsigned int numentries)
{
map<ComboAddress, unsigned int, ComboAddress::addressOnlyLessThan> counts;
uint64_t total=0;
for (const auto& shard : d_shards) {
{
std::lock_guard<std::mutex> rl(shard->queryLock);
for(const auto& q : shard->queryRing) {
counts[q.requestor]+=q.size;
total+=q.size;
}
}
{
std::lock_guard<std::mutex> rl(shard->respLock);
for(const auto& r : shard->respRing) {
counts[r.requestor]+=r.size;
total+=r.size;
}
}
}
typedef vector<pair<unsigned int, ComboAddress>> ret_t;
ret_t rcounts;
rcounts.reserve(counts.size());
for(const auto& p : counts)
rcounts.push_back({p.second, p.first});
numentries = rcounts.size() < numentries ? rcounts.size() : numentries;
partial_sort(rcounts.begin(), rcounts.begin()+numentries, rcounts.end(), [](const ret_t::value_type&a, const ret_t::value_type&b)
{
return(b.first < a.first);
});
std::unordered_map<int, vector<boost::variant<string,double>>> ret;
uint64_t rest = 0;
unsigned int count = 1;
for(const auto& rc : rcounts) {
if(count==numentries+1) {
rest+=rc.first;
}
else {
ret.insert({count++, {rc.second.toString(), rc.first, 100.0*rc.first/total}});
}
}
ret.insert({count, {"Rest", rest, total > 0 ? 100.0*rest/total : 100.0}});
return ret;
}
|