in util/Stats.cpp [226:285]
void Histogram::print(std::ostream& os) const {
const int64_t multiplier = divider_;
// calculate the last bucket index
int32_t lastIdx = -1;
for (int i = kLastIndex; i >= 0; --i) {
if (hdata_[i] > 0) {
lastIdx = i;
break;
}
}
if (lastIdx == -1) {
os << "no data" << std::endl;
return;
}
// comment out header in gnuplot data file
os << "# ";
Counter::printCounterHeader(os);
os << ","; // awk -F, '/^count/ {sum+=$6} END {print "sum is", sum}'
Counter::print(os); // the base counter part
os << std::endl << "# range, mid point, percentile, count" << std::endl;
int64_t prev = 0;
int64_t total = 0;
const int64_t ctrTotal = getCount();
auto oldPrecision = os.precision(5);
// we can combine this loop and the calcPercentile() one but it's
// easier to read/maintain/test when separated and it's only 2 pass on
// very little data
// output the data of each bucket of the histogram
for (size_t i = 0; i <= static_cast<size_t>(lastIdx); ++i) {
total += hdata_[i];
// data in each row is separated by comma (",")
if (i > 0) {
os << ">= " << multiplier * prev + offset_ << " ";
}
double perc = 100. * (double)total / ctrTotal;
if (i < kLastIndex) {
int64_t cur = Histogram::kHistogramBuckets[i];
os << "< " << multiplier * cur + offset_ << " ";
double midpt = multiplier * (prev + cur) / 2 + offset_;
os << ", " << midpt << " ";
prev = cur;
} else {
os << ", " << multiplier * prev + offset_ << " ";
}
os << ", " << perc << ", " << hdata_[i] << std::endl;
}
// print the information of target percentiles
os.precision(1);
os << std::fixed << "# target " << percentile1_ << "%,"
<< calcPercentile(percentile1_) << std::endl
<< "# target " << percentile2_ << "%," << calcPercentile(percentile2_)
<< std::endl;
os.unsetf(std::ios_base::floatfield);
os.precision(oldPrecision);
}