histogram.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <cassert>
  11. #include <map>
  12. #include <mutex>
  13. #include <string>
  14. #include <vector>
  15. #include "rocksdb/statistics.h"
  16. namespace ROCKSDB_NAMESPACE {
  17. class HistogramBucketMapper {
  18. public:
  19. HistogramBucketMapper();
  20. // converts a value to the bucket index.
  21. size_t IndexForValue(uint64_t value) const;
  22. // number of buckets required.
  23. size_t BucketCount() const { return bucketValues_.size(); }
  24. uint64_t LastValue() const { return maxBucketValue_; }
  25. uint64_t FirstValue() const { return minBucketValue_; }
  26. uint64_t BucketLimit(const size_t bucketNumber) const {
  27. assert(bucketNumber < BucketCount());
  28. return bucketValues_[bucketNumber];
  29. }
  30. private:
  31. std::vector<uint64_t> bucketValues_;
  32. uint64_t maxBucketValue_;
  33. uint64_t minBucketValue_;
  34. };
  35. struct HistogramStat {
  36. HistogramStat();
  37. ~HistogramStat() {}
  38. HistogramStat(const HistogramStat&) = delete;
  39. HistogramStat& operator=(const HistogramStat&) = delete;
  40. void Clear();
  41. bool Empty() const;
  42. void Add(uint64_t value);
  43. void Merge(const HistogramStat& other);
  44. inline uint64_t min() const { return min_.load(std::memory_order_relaxed); }
  45. inline uint64_t max() const { return max_.load(std::memory_order_relaxed); }
  46. inline uint64_t num() const { return num_.load(std::memory_order_relaxed); }
  47. inline uint64_t sum() const { return sum_.load(std::memory_order_relaxed); }
  48. inline uint64_t sum_squares() const {
  49. return sum_squares_.load(std::memory_order_relaxed);
  50. }
  51. inline uint64_t bucket_at(size_t b) const {
  52. return buckets_[b].load(std::memory_order_relaxed);
  53. }
  54. double Median() const;
  55. double Percentile(double p) const;
  56. double Average() const;
  57. double StandardDeviation() const;
  58. void Data(HistogramData* const data) const;
  59. std::string ToString() const;
  60. // To be able to use HistogramStat as thread local variable, it
  61. // cannot have dynamic allocated member. That's why we're
  62. // using manually values from BucketMapper
  63. std::atomic_uint_fast64_t min_;
  64. std::atomic_uint_fast64_t max_;
  65. std::atomic_uint_fast64_t num_;
  66. std::atomic_uint_fast64_t sum_;
  67. std::atomic_uint_fast64_t sum_squares_;
  68. std::atomic_uint_fast64_t buckets_[109]; // 109==BucketMapper::BucketCount()
  69. const uint64_t num_buckets_;
  70. };
  71. class Histogram {
  72. public:
  73. Histogram() {}
  74. virtual ~Histogram() {}
  75. virtual void Clear() = 0;
  76. virtual bool Empty() const = 0;
  77. virtual void Add(uint64_t value) = 0;
  78. virtual void Merge(const Histogram&) = 0;
  79. virtual std::string ToString() const = 0;
  80. virtual const char* Name() const = 0;
  81. virtual uint64_t min() const = 0;
  82. virtual uint64_t max() const = 0;
  83. virtual uint64_t num() const = 0;
  84. virtual double Median() const = 0;
  85. virtual double Percentile(double p) const = 0;
  86. virtual double Average() const = 0;
  87. virtual double StandardDeviation() const = 0;
  88. virtual void Data(HistogramData* const data) const = 0;
  89. };
  90. class HistogramImpl : public Histogram {
  91. public:
  92. HistogramImpl() { Clear(); }
  93. HistogramImpl(const HistogramImpl&) = delete;
  94. HistogramImpl& operator=(const HistogramImpl&) = delete;
  95. void Clear() override;
  96. bool Empty() const override;
  97. void Add(uint64_t value) override;
  98. void Merge(const Histogram& other) override;
  99. void Merge(const HistogramImpl& other);
  100. std::string ToString() const override;
  101. const char* Name() const override { return "HistogramImpl"; }
  102. uint64_t min() const override { return stats_.min(); }
  103. uint64_t max() const override { return stats_.max(); }
  104. uint64_t num() const override { return stats_.num(); }
  105. double Median() const override;
  106. double Percentile(double p) const override;
  107. double Average() const override;
  108. double StandardDeviation() const override;
  109. void Data(HistogramData* const data) const override;
  110. virtual ~HistogramImpl() {}
  111. inline HistogramStat& TEST_GetStats() { return stats_; }
  112. private:
  113. HistogramStat stats_;
  114. std::mutex mutex_;
  115. };
  116. } // namespace ROCKSDB_NAMESPACE