histogram.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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 "rocksdb/statistics.h"
  11. #include <cassert>
  12. #include <string>
  13. #include <vector>
  14. #include <map>
  15. #include <mutex>
  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 {
  24. return bucketValues_.size();
  25. }
  26. uint64_t LastValue() const {
  27. return maxBucketValue_;
  28. }
  29. uint64_t FirstValue() const {
  30. return minBucketValue_;
  31. }
  32. uint64_t BucketLimit(const size_t bucketNumber) const {
  33. assert(bucketNumber < BucketCount());
  34. return bucketValues_[bucketNumber];
  35. }
  36. private:
  37. std::vector<uint64_t> bucketValues_;
  38. uint64_t maxBucketValue_;
  39. uint64_t minBucketValue_;
  40. std::map<uint64_t, uint64_t> valueIndexMap_;
  41. };
  42. struct HistogramStat {
  43. HistogramStat();
  44. ~HistogramStat() {}
  45. HistogramStat(const HistogramStat&) = delete;
  46. HistogramStat& operator=(const HistogramStat&) = delete;
  47. void Clear();
  48. bool Empty() const;
  49. void Add(uint64_t value);
  50. void Merge(const HistogramStat& other);
  51. inline uint64_t min() const { return min_.load(std::memory_order_relaxed); }
  52. inline uint64_t max() const { return max_.load(std::memory_order_relaxed); }
  53. inline uint64_t num() const { return num_.load(std::memory_order_relaxed); }
  54. inline uint64_t sum() const { return sum_.load(std::memory_order_relaxed); }
  55. inline uint64_t sum_squares() const {
  56. return sum_squares_.load(std::memory_order_relaxed);
  57. }
  58. inline uint64_t bucket_at(size_t b) const {
  59. return buckets_[b].load(std::memory_order_relaxed);
  60. }
  61. double Median() const;
  62. double Percentile(double p) const;
  63. double Average() const;
  64. double StandardDeviation() const;
  65. void Data(HistogramData* const data) const;
  66. std::string ToString() const;
  67. // To be able to use HistogramStat as thread local variable, it
  68. // cannot have dynamic allocated member. That's why we're
  69. // using manually values from BucketMapper
  70. std::atomic_uint_fast64_t min_;
  71. std::atomic_uint_fast64_t max_;
  72. std::atomic_uint_fast64_t num_;
  73. std::atomic_uint_fast64_t sum_;
  74. std::atomic_uint_fast64_t sum_squares_;
  75. std::atomic_uint_fast64_t buckets_[109]; // 109==BucketMapper::BucketCount()
  76. const uint64_t num_buckets_;
  77. };
  78. class Histogram {
  79. public:
  80. Histogram() {}
  81. virtual ~Histogram() {};
  82. virtual void Clear() = 0;
  83. virtual bool Empty() const = 0;
  84. virtual void Add(uint64_t value) = 0;
  85. virtual void Merge(const Histogram&) = 0;
  86. virtual std::string ToString() const = 0;
  87. virtual const char* Name() const = 0;
  88. virtual uint64_t min() const = 0;
  89. virtual uint64_t max() const = 0;
  90. virtual uint64_t num() const = 0;
  91. virtual double Median() const = 0;
  92. virtual double Percentile(double p) const = 0;
  93. virtual double Average() const = 0;
  94. virtual double StandardDeviation() const = 0;
  95. virtual void Data(HistogramData* const data) const = 0;
  96. };
  97. class HistogramImpl : public Histogram {
  98. public:
  99. HistogramImpl() { Clear(); }
  100. HistogramImpl(const HistogramImpl&) = delete;
  101. HistogramImpl& operator=(const HistogramImpl&) = delete;
  102. virtual void Clear() override;
  103. virtual bool Empty() const override;
  104. virtual void Add(uint64_t value) override;
  105. virtual void Merge(const Histogram& other) override;
  106. void Merge(const HistogramImpl& other);
  107. virtual std::string ToString() const override;
  108. virtual const char* Name() const override { return "HistogramImpl"; }
  109. virtual uint64_t min() const override { return stats_.min(); }
  110. virtual uint64_t max() const override { return stats_.max(); }
  111. virtual uint64_t num() const override { return stats_.num(); }
  112. virtual double Median() const override;
  113. virtual double Percentile(double p) const override;
  114. virtual double Average() const override;
  115. virtual double StandardDeviation() const override;
  116. virtual void Data(HistogramData* const data) const override;
  117. virtual ~HistogramImpl() {}
  118. private:
  119. HistogramStat stats_;
  120. std::mutex mutex_;
  121. };
  122. } // namespace ROCKSDB_NAMESPACE