Index: third_party/grpc/src/core/statistics/window_stats.h |
diff --git a/third_party/grpc/src/core/statistics/window_stats.h b/third_party/grpc/src/core/statistics/window_stats.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f4732e96a02e4083e9bbca550ae84436e7f717e0 |
--- /dev/null |
+++ b/third_party/grpc/src/core/statistics/window_stats.h |
@@ -0,0 +1,173 @@ |
+/* |
+ * |
+ * Copyright 2015, Google Inc. |
+ * All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions are |
+ * met: |
+ * |
+ * * Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * * Redistributions in binary form must reproduce the above |
+ * copyright notice, this list of conditions and the following disclaimer |
+ * in the documentation and/or other materials provided with the |
+ * distribution. |
+ * * Neither the name of Google Inc. nor the names of its |
+ * contributors may be used to endorse or promote products derived from |
+ * this software without specific prior written permission. |
+ * |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ * |
+ */ |
+ |
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H |
+#define GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H |
+ |
+#include <grpc/support/time.h> |
+ |
+/* Keep rolling sums of a user-defined statistic (containing a number of |
+ measurements) over a a number of time intervals ("windows"). For example, |
+ you can use a window_stats object to answer questions such as |
+ "Approximately how many RPCs/s did I receive over the past minute, and |
+ approximately how many bytes did I send out over that period?". |
+ |
+ The type of data to record, and the time intervals to keep are specified |
+ when creating the object via a call to census_window_stats_create(). |
+ |
+ A window's interval is divided into one or more "buckets"; the interval |
+ must be divisible by the number of buckets. Internally, these buckets |
+ control the granularity of window_stats' measurements. Increasing the |
+ number of buckets lets the object respond more quickly to changes in the |
+ overall rate of data added into the object, at the cost of additional |
+ memory usage. |
+ |
+ Here's some code which keeps one minute/hour measurements for two values |
+ (latency in seconds and bytes transferred), with each interval divided into |
+ 4 buckets. |
+ |
+ typedef struct my_stat { |
+ double latency; |
+ int bytes; |
+ } my_stat; |
+ |
+ void add_my_stat(void* base, const void* addme) { |
+ my_stat* b = (my_stat*)base; |
+ const my_stat* a = (const my_stat*)addme; |
+ b->latency += a->latency; |
+ b->bytes += a->bytes; |
+ } |
+ |
+ void add_proportion_my_stat(double p, void* base, const void* addme) { |
+ (my_stat*)result->latency += p * (const my_stat*)base->latency; |
+ (my_stat*)result->bytes += p * (const my_stat*)base->bytes; |
+ } |
+ |
+ #define kNumIntervals 2 |
+ #define kMinInterval 0 |
+ #define kHourInterval 1 |
+ #define kNumBuckets 4 |
+ |
+ const struct census_window_stats_stat_info kMyStatInfo |
+ = { sizeof(my_stat), NULL, add_my_stat, add_proportion_my_stat }; |
+ gpr_timespec intervals[kNumIntervals] = {{60, 0}, {3600, 0}}; |
+ my_stat stat; |
+ my_stat sums[kNumIntervals]; |
+ census_window_stats_sums result[kNumIntervals]; |
+ struct census_window_stats* stats |
+ = census_window_stats_create(kNumIntervals, intervals, kNumBuckets, |
+ &kMyStatInfo); |
+ // Record a new event, taking 15.3ms, transferring 1784 bytes. |
+ stat.latency = 0.153; |
+ stat.bytes = 1784; |
+ census_window_stats_add(stats, gpr_now(GPR_CLOCK_REALTIME), &stat); |
+ // Get sums and print them out |
+ result[kMinInterval].statistic = &sums[kMinInterval]; |
+ result[kHourInterval].statistic = &sums[kHourInterval]; |
+ census_window_stats_get_sums(stats, gpr_now(GPR_CLOCK_REALTIME), result); |
+ printf("%d events/min, average time %gs, average bytes %g\n", |
+ result[kMinInterval].count, |
+ (my_stat*)result[kMinInterval].statistic->latency / |
+ result[kMinInterval].count, |
+ (my_stat*)result[kMinInterval].statistic->bytes / |
+ result[kMinInterval].count |
+ ); |
+ printf("%d events/hr, average time %gs, average bytes %g\n", |
+ result[kHourInterval].count, |
+ (my_stat*)result[kHourInterval].statistic->latency / |
+ result[kHourInterval].count, |
+ (my_stat*)result[kHourInterval].statistic->bytes / |
+ result[kHourInterval].count |
+ ); |
+*/ |
+ |
+/* Opaque structure for representing window_stats object */ |
+struct census_window_stats; |
+ |
+/* Information provided by API user on the information they want to record */ |
+typedef struct census_window_stats_stat_info { |
+ /* Number of bytes in user-defined object. */ |
+ size_t stat_size; |
+ /* Function to initialize a user-defined statistics object. If this is set |
+ * to NULL, then the object will be zero-initialized. */ |
+ void (*stat_initialize)(void *stat); |
+ /* Function to add one user-defined statistics object ('addme') to 'base' */ |
+ void (*stat_add)(void *base, const void *addme); |
+ /* As for previous function, but only add a proportion 'p'. This API will |
+ currently only use 'p' values in the range [0,1], but other values are |
+ possible in the future, and should be supported. */ |
+ void (*stat_add_proportion)(double p, void *base, const void *addme); |
+} census_window_stats_stat_info; |
+ |
+/* Create a new window_stats object. 'nintervals' is the number of |
+ 'intervals', and must be >=1. 'granularity' is the number of buckets, with |
+ a larger number using more memory, but providing greater accuracy of |
+ results. 'granularity should be > 2. We also require that each interval be |
+ at least 10 * 'granularity' nanoseconds in size. 'stat_info' contains |
+ information about the statistic to be gathered. Intervals greater than ~192 |
+ years will be treated as essentially infinite in size. This function will |
+ GPR_ASSERT() if the object cannot be created or any of the parameters have |
+ invalid values. This function is thread-safe. */ |
+struct census_window_stats *census_window_stats_create( |
+ int nintervals, const gpr_timespec intervals[], int granularity, |
+ const census_window_stats_stat_info *stat_info); |
+ |
+/* Add a new measurement (in 'stat_value'), as of a given time ('when'). |
+ This function is thread-compatible. */ |
+void census_window_stats_add(struct census_window_stats *wstats, |
+ const gpr_timespec when, const void *stat_value); |
+ |
+/* Structure used to record a single intervals sum for a given statistic */ |
+typedef struct census_window_stats_sum { |
+ /* Total count of samples. Note that because some internal interpolation |
+ is performed, the count of samples returned for each interval may not be an |
+ integral value. */ |
+ double count; |
+ /* Sum for statistic */ |
+ void *statistic; |
+} census_window_stats_sums; |
+ |
+/* Retrieve a set of all values stored in a window_stats object 'wstats'. The |
+ number of 'sums' MUST be the same as the number 'nintervals' used in |
+ census_window_stats_create(). This function is thread-compatible. */ |
+void census_window_stats_get_sums(const struct census_window_stats *wstats, |
+ const gpr_timespec when, |
+ struct census_window_stats_sum sums[]); |
+ |
+/* Destroy a window_stats object. Once this function has been called, the |
+ object will no longer be usable from any of the above functions (and |
+ calling them will most likely result in a NULL-pointer dereference or |
+ assertion failure). This function is thread-compatible. */ |
+void census_window_stats_destroy(struct census_window_stats *wstats); |
+ |
+#endif /* GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H */ |