// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). // // Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. #pragma once #include #include #include #include #include #include "rocksdb/statistics.h" namespace ROCKSDB_NAMESPACE { class HistogramBucketMapper { public: HistogramBucketMapper(); // converts a value to the bucket index. size_t IndexForValue(uint64_t value) const; // number of buckets required. size_t BucketCount() const { return bucketValues_.size(); } uint64_t LastValue() const { return maxBucketValue_; } uint64_t FirstValue() const { return minBucketValue_; } uint64_t BucketLimit(const size_t bucketNumber) const { assert(bucketNumber < BucketCount()); return bucketValues_[bucketNumber]; } private: std::vector bucketValues_; uint64_t maxBucketValue_; uint64_t minBucketValue_; }; struct HistogramStat { HistogramStat(); ~HistogramStat() {} HistogramStat(const HistogramStat&) = delete; HistogramStat& operator=(const HistogramStat&) = delete; void Clear(); bool Empty() const; void Add(uint64_t value); void Merge(const HistogramStat& other); inline uint64_t min() const { return min_.load(std::memory_order_relaxed); } inline uint64_t max() const { return max_.load(std::memory_order_relaxed); } inline uint64_t num() const { return num_.load(std::memory_order_relaxed); } inline uint64_t sum() const { return sum_.load(std::memory_order_relaxed); } inline uint64_t sum_squares() const { return sum_squares_.load(std::memory_order_relaxed); } inline uint64_t bucket_at(size_t b) const { return buckets_[b].load(std::memory_order_relaxed); } double Median() const; double Percentile(double p) const; double Average() const; double StandardDeviation() const; void Data(HistogramData* const data) const; std::string ToString() const; // To be able to use HistogramStat as thread local variable, it // cannot have dynamic allocated member. That's why we're // using manually values from BucketMapper std::atomic_uint_fast64_t min_; std::atomic_uint_fast64_t max_; std::atomic_uint_fast64_t num_; std::atomic_uint_fast64_t sum_; std::atomic_uint_fast64_t sum_squares_; std::atomic_uint_fast64_t buckets_[109]; // 109==BucketMapper::BucketCount() const uint64_t num_buckets_; }; class Histogram { public: Histogram() {} virtual ~Histogram(){} virtual void Clear() = 0; virtual bool Empty() const = 0; virtual void Add(uint64_t value) = 0; virtual void Merge(const Histogram&) = 0; virtual std::string ToString() const = 0; virtual const char* Name() const = 0; virtual uint64_t min() const = 0; virtual uint64_t max() const = 0; virtual uint64_t num() const = 0; virtual double Median() const = 0; virtual double Percentile(double p) const = 0; virtual double Average() const = 0; virtual double StandardDeviation() const = 0; virtual void Data(HistogramData* const data) const = 0; }; class HistogramImpl : public Histogram { public: HistogramImpl() { Clear(); } HistogramImpl(const HistogramImpl&) = delete; HistogramImpl& operator=(const HistogramImpl&) = delete; void Clear() override; bool Empty() const override; void Add(uint64_t value) override; void Merge(const Histogram& other) override; void Merge(const HistogramImpl& other); std::string ToString() const override; const char* Name() const override { return "HistogramImpl"; } uint64_t min() const override { return stats_.min(); } uint64_t max() const override { return stats_.max(); } uint64_t num() const override { return stats_.num(); } double Median() const override; double Percentile(double p) const override; double Average() const override; double StandardDeviation() const override; void Data(HistogramData* const data) const override; virtual ~HistogramImpl() {} inline HistogramStat& TEST_GetStats() { return stats_; } private: HistogramStat stats_; std::mutex mutex_; }; } // namespace ROCKSDB_NAMESPACE