blob: f8948c8cdaef2c09edf94a935ee99865984d5b53 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
#include <fbl/function.h>
#include <zircon/compiler.h>
namespace cobalt_client {
// Describes an histogram, and provides data for mapping a value to a given bucket.
// Every histogram contains two additional buckets, one at index 0 and bucket_count + 1.
// These buckets are used to store underflow and overflow respectively.
//
// buckets = [-inf, min_value) ...... [max_value, +inf)
//
// Parameters are calculated by the factory methods based on the input parameters,
// so that expectations are met.
//
// If using cobalt to flush your observations to the backend, this options should match
// your metric definitions for correct behavior. Mismatch with the respective metric definition
// will not allow proper collection and aggregation of metrics in the backend.
struct HistogramOptions {
enum class Type {
// Each bucket is described in the following form:
// range(i) = [ b * i + c, b * {i +1} + c)
// i = (val - c) / b
kLinear,
// Each bucket is described in the following form:
// range(i) = [ b * a^i + c, b * a^{i+1} + c)
// The cost of this type is O(1), because:
// i = floor(log (val - c) - log b)/log a
kExponential,
};
// Returns HistogramOptions for a Histogram whose bucket size follow an exponential progression.
// |scalar| * |base|^(current_step) + |offset| - |scalar| = lowerbound(current_step).
// offset' = |offset| - |scalar|
// |scalar| * |base|^(current_step) + offset' = lowerbound(current_step).
static HistogramOptions Exponential(uint32_t bucket_count, uint32_t base, uint32_t scalar,
int64_t offset);
// Returns HistogramOptions for a Histogram whose bucket size follow an exponential progression.
// |scalar| * current_step + offset = lowerbound(current_step).
static HistogramOptions Linear(uint32_t bucket_count, uint32_t scalar, int64_t offset);
HistogramOptions() = default;
HistogramOptions(const HistogramOptions&);
// Sanity check.
bool IsValid() const {
switch (type) {
case Type::kExponential:
if (base == 0) {
return false;
}
__FALLTHROUGH;
case Type::kLinear:
if (scalar == 0 || bucket_count == 0) {
return false;
}
break;
}
return true;
}
// This parameters should not be set manually.
// Function used for mapping a value to a given bucket.
fbl::Function<uint32_t(double, const HistogramOptions&)> map_fn = nullptr;
// Function used for mapping a bucket to its lowerbound.
fbl::Function<double(uint32_t, const HistogramOptions&)> reverse_map_fn = nullptr;
// Base to describe the width of each step, in |kExponentialWidth|.
double base = 1;
// Scalar used by the type. This scales the width of each step.
double scalar = 1;
// This matchest offset', which is calculated depending on the histogram type.
double offset = 0;
// Number of buckets needed.
uint32_t bucket_count = 1;
// Type of the histogram to be constructed.
Type type;
};
} // namespace cobalt_client