Skip to content

Commit d54463c

Browse files
committed
core+proto: Generalize histogram utilities
Histogram functionality currently used in the Measure module will soon be used in other modules. This commit moves some helper functions and protobufs so they can be shared.
1 parent adf7652 commit d54463c

5 files changed

Lines changed: 81 additions & 43 deletions

File tree

core/modules/measure.cc

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,22 +142,6 @@ void Measure::ProcessBatch(Context *ctx, bess::PacketBatch *batch) {
142142
RunNextModule(ctx, batch);
143143
}
144144

145-
template <typename T>
146-
static void SetHistogram(
147-
bess::pb::MeasureCommandGetSummaryResponse::Histogram *r, const T &hist,
148-
uint64_t bucket_width) {
149-
r->set_count(hist.count);
150-
r->set_above_range(hist.above_range);
151-
r->set_resolution_ns(bucket_width);
152-
r->set_min_ns(hist.min);
153-
r->set_max_ns(hist.max);
154-
r->set_avg_ns(hist.avg);
155-
r->set_total_ns(hist.total);
156-
for (const auto &val : hist.percentile_values) {
157-
r->add_percentile_values_ns(val);
158-
}
159-
}
160-
161145
void Measure::Clear() {
162146
// vector initialization is expensive thus should be out of critical section
163147
decltype(rtt_hist_) new_rtt_hist(rtt_hist_.num_buckets(),
@@ -175,16 +159,6 @@ void Measure::Clear() {
175159
mcs_unlock(&lock_, &mynode);
176160
}
177161

178-
static bool IsValidPercentiles(const std::vector<double> &percentiles) {
179-
if (percentiles.empty()) {
180-
return true;
181-
}
182-
183-
return std::is_sorted(percentiles.cbegin(), percentiles.cend()) &&
184-
*std::min_element(percentiles.cbegin(), percentiles.cend()) >= 0.0 &&
185-
*std::max_element(percentiles.cbegin(), percentiles.cend()) <= 100.0;
186-
}
187-
188162
CommandResponse Measure::CommandGetSummary(
189163
const bess::pb::MeasureCommandGetSummaryArg &arg) {
190164
bess::pb::MeasureCommandGetSummaryResponse r;
@@ -211,8 +185,8 @@ CommandResponse Measure::CommandGetSummary(
211185
const auto &rtt = rtt_hist_.Summarize(latency_percentiles);
212186
const auto &jitter = jitter_hist_.Summarize(jitter_percentiles);
213187

214-
SetHistogram(r.mutable_latency(), rtt, rtt_hist_.bucket_width());
215-
SetHistogram(r.mutable_jitter(), jitter, jitter_hist_.bucket_width());
188+
SetHistogram(r.mutable_latency_ns(), rtt);
189+
SetHistogram(r.mutable_jitter_ns(), jitter);
216190

217191
if (arg.clear()) {
218192
// Note that some samples might be lost due to the small gap between

core/utils/histogram.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) 2016-2019, Nefeli Networks, Inc.
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright notice, this
8+
// list of conditions and the following disclaimer.
9+
//
10+
// * Redistributions in binary form must reproduce the above copyright notice,
11+
// this list of conditions and the following disclaimer in the documentation
12+
// and/or other materials provided with the distribution.
13+
//
14+
// * Neither the names of the copyright holders nor the names of their
15+
// contributors may be used to endorse or promote products derived from this
16+
// software without specific prior written permission.
17+
//
18+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
// POSSIBILITY OF SUCH DAMAGE.
29+
30+
#include "histogram.h"
31+
32+
bool IsValidPercentiles(const std::vector<double> &percentiles) {
33+
if (percentiles.empty()) {
34+
return true;
35+
}
36+
37+
return std::is_sorted(percentiles.cbegin(), percentiles.cend()) &&
38+
*std::min_element(percentiles.cbegin(), percentiles.cend()) >= 0.0 &&
39+
*std::max_element(percentiles.cbegin(), percentiles.cend()) <= 100.0;
40+
}

core/utils/histogram.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) 2014-2016, The Regents of the University of California.
2-
// Copyright (c) 2016-2017, Nefeli Networks, Inc.
2+
// Copyright (c) 2016-2019, Nefeli Networks, Inc.
33
// All rights reserved.
44
//
55
// Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,8 @@
4242

4343
#include <glog/logging.h>
4444

45+
#include "../pb/util_msg.pb.h"
46+
4547
// Class for general purpose histogram. T generally should be an
4648
// integral type, though floating point types will also work.
4749
// A bin b_i corresponds for the range [i * width, (i + 1) * width)
@@ -52,7 +54,9 @@ class Histogram {
5254
public:
5355
static_assert(std::is_arithmetic<T>::value, "Arithmetic type required.");
5456
struct Summary {
55-
size_t count; // # of all samples. If 0, min, max and avg are also 0
57+
size_t num_buckets; // Number of buckets in the histogram
58+
size_t bucket_width; // Resolution of the measured data
59+
size_t count; // # of samples (including above_range). If 0, min, max and avg are also 0
5660
size_t above_range; // # of samples beyond the histogram range
5761
T min; // Min value
5862
T max; // Max value. May be underestimated if above_range > 0
@@ -124,6 +128,8 @@ class Histogram {
124128
// percentile_values
125129
const Summary Summarize(const std::vector<double> &percentiles = {}) const {
126130
Summary ret = {};
131+
ret.num_buckets = num_buckets();
132+
ret.bucket_width = bucket_width_;
127133
uint64_t count = std::accumulate(buckets_.begin(), buckets_.end(), 0);
128134
ret.count = count;
129135
ret.above_range = buckets_.back();
@@ -201,4 +207,21 @@ class Histogram {
201207
std::vector<std::atomic<uint64_t>> buckets_;
202208
};
203209

210+
bool IsValidPercentiles(const std::vector<double> &percentiles);
211+
212+
template <typename T>
213+
void SetHistogram(bess::pb::HistogramSummary *r, const T &summary) {
214+
r->set_num_buckets(summary.num_buckets);
215+
r->set_bucket_width(summary.bucket_width);
216+
r->set_count(summary.count);
217+
r->set_above_range(summary.above_range);
218+
r->set_min(summary.min);
219+
r->set_max(summary.max);
220+
r->set_avg(summary.avg);
221+
r->set_total(summary.total);
222+
for (const auto &val : summary.percentile_values) {
223+
r->add_percentile_values(val);
224+
}
225+
}
226+
204227
#endif // BESS_UTILS_HISTOGRAM_H_

protobuf/module_msg.proto

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,22 +243,11 @@ message MeasureCommandGetSummaryArg {
243243
* may not be a multiple of the resolution.
244244
*/
245245
message MeasureCommandGetSummaryResponse {
246-
message Histogram {
247-
uint64 count = 1; /// Total # of measured data points, including above_range
248-
uint64 above_range = 2; /// # of data points for the "too large value" bucket
249-
uint64 resolution_ns = 8; /// resolution of measured data
250-
uint64 min_ns = 3;
251-
uint64 avg_ns = 4;
252-
uint64 max_ns = 5;
253-
uint64 total_ns = 6;
254-
repeated uint64 percentile_values_ns = 7;
255-
}
256-
257246
double timestamp = 1; /// Seconds since boot.
258247
uint64 packets = 2; /// Total # of packets seen by this module.
259248
uint64 bits = 3; /// Total # of bits seen by this module.
260-
Histogram latency = 4;
261-
Histogram jitter = 5;
249+
HistogramSummary latency_ns = 4;
250+
HistogramSummary jitter_ns = 5;
262251
}
263252

264253

protobuf/util_msg.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,15 @@ message FieldData {
4949
}
5050
}
5151

52+
/// The HistogramSummary message carries summary statistics about a histogram.
53+
message HistogramSummary {
54+
uint64 num_buckets = 1; /// Number of buckets in the histogram
55+
uint64 bucket_width = 2; /// Resolution of the measured data
56+
uint64 count = 3; /// # of samples (including above_range). If 0, min, max and avg are also 0
57+
uint64 above_range = 4; /// # of samples beyond the histogram range
58+
uint64 min = 5; /// Min value
59+
uint64 max = 6; /// Max value. May be underestimated if above_range > 0
60+
uint64 avg = 7; /// Average of all samples (== total / count)
61+
uint64 total = 8; /// Total sum of all samples
62+
repeated uint64 percentile_values = 9;
63+
}

0 commit comments

Comments
 (0)