| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 | //  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 "rocksdb/statistics.h"#include <cassert>#include <string>#include <vector>#include <map>#include <mutex>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<uint64_t> bucketValues_;  uint64_t maxBucketValue_;  uint64_t minBucketValue_;  std::map<uint64_t, uint64_t> valueIndexMap_;};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;  virtual void Clear() override;  virtual bool Empty() const override;  virtual void Add(uint64_t value) override;  virtual void Merge(const Histogram& other) override;  void Merge(const HistogramImpl& other);  virtual std::string ToString() const override;  virtual const char* Name() const override { return "HistogramImpl"; }  virtual uint64_t min() const override { return stats_.min(); }  virtual uint64_t max() const override { return stats_.max(); }  virtual uint64_t num() const override { return stats_.num(); }  virtual double Median() const override;  virtual double Percentile(double p) const override;  virtual double Average() const override;  virtual double StandardDeviation() const override;  virtual void Data(HistogramData* const data) const override;  virtual ~HistogramImpl() {} private:  HistogramStat stats_;  std::mutex mutex_;};}  // namespace ROCKSDB_NAMESPACE
 |