stat_collector.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Tencent is pleased to support the open source community by making wwsearch
  3. * available.
  4. *
  5. * Copyright (C) 2018-present Tencent. All Rights Reserved.
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  8. * use this file except in compliance with the License. You may obtain a copy of
  9. * the License at
  10. *
  11. * https://opensource.org/licenses/Apache-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OF ANY KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations under the License.
  17. */
  18. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  19. // This source code is licensed under both the GPLv2 (found in the
  20. // COPYING file in the root directory) and Apache 2.0 License
  21. // (found in the LICENSE.Apache file in the root directory).
  22. //
  23. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  24. // Use of this source code is governed by a BSD-style license that can be
  25. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  26. #pragma once
  27. #include <sys/time.h>
  28. #include <atomic>
  29. #include <cassert>
  30. #include <ctime>
  31. #include <map>
  32. #include <mutex>
  33. #include <string>
  34. #include <vector>
  35. namespace wwsearch {
  36. class Counter {
  37. public:
  38. Counter() : val_(0) {}
  39. int64_t Add(int64_t v) { return val_.fetch_add(v); }
  40. int64_t Sub(int64_t v) { return val_.fetch_sub(v); }
  41. int64_t Inc() { return val_.fetch_add(1); }
  42. int64_t Dec() { return val_.fetch_sub(1); }
  43. int64_t Get() const { return val_.load(); }
  44. void Set(int64_t v) { return val_.store(v); }
  45. void Clear() { return val_.store(0); }
  46. private:
  47. std::atomic<int64_t> val_;
  48. };
  49. class Time {
  50. public:
  51. static uint64_t NowMicros() {
  52. static constexpr uint64_t kUsecondsPerSecond = 1000000;
  53. struct ::timeval tv;
  54. ::gettimeofday(&tv, nullptr);
  55. return static_cast<uint64_t>(tv.tv_sec) * kUsecondsPerSecond + tv.tv_usec;
  56. }
  57. static uint64_t NowNanos() {
  58. struct timespec ts;
  59. clock_gettime(CLOCK_MONOTONIC, &ts);
  60. return static_cast<uint64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
  61. }
  62. static uint64_t CalculateConsumeTimeUs(const struct ::timeval& begin,
  63. const struct ::timeval& end) {
  64. if (end.tv_sec < begin.tv_sec) {
  65. assert(false);
  66. return 0;
  67. }
  68. return ((end.tv_sec - begin.tv_sec) * 1000000 +
  69. (end.tv_usec - begin.tv_usec));
  70. }
  71. };
  72. struct HistogramData {
  73. double median;
  74. double percentile95;
  75. double percentile99;
  76. double average;
  77. double standard_deviation;
  78. // zero-initialize new members since old Statistics::histogramData()
  79. // implementations won't write them.
  80. double max = 0.0;
  81. uint64_t count = 0;
  82. uint64_t sum = 0;
  83. };
  84. class HistogramBucketMapper {
  85. public:
  86. HistogramBucketMapper();
  87. // converts a value to the bucket index.
  88. size_t IndexForValue(uint64_t value) const;
  89. // number of buckets required.
  90. size_t BucketCount() const { return bucketValues_.size(); }
  91. uint64_t LastValue() const { return maxBucketValue_; }
  92. uint64_t FirstValue() const { return minBucketValue_; }
  93. uint64_t BucketLimit(const size_t bucketNumber) const {
  94. assert(bucketNumber < BucketCount());
  95. return bucketValues_[bucketNumber];
  96. }
  97. private:
  98. std::vector<uint64_t> bucketValues_;
  99. uint64_t maxBucketValue_;
  100. uint64_t minBucketValue_;
  101. std::map<uint64_t, uint64_t> valueIndexMap_;
  102. };
  103. struct HistogramStat {
  104. HistogramStat();
  105. ~HistogramStat() {}
  106. HistogramStat(const HistogramStat&) = delete;
  107. HistogramStat& operator=(const HistogramStat&) = delete;
  108. void Clear();
  109. bool Empty() const;
  110. void Add(uint64_t value);
  111. void Merge(const HistogramStat& other);
  112. inline uint64_t min() const { return min_.load(std::memory_order_relaxed); }
  113. inline uint64_t max() const { return max_.load(std::memory_order_relaxed); }
  114. inline uint64_t num() const { return num_.load(std::memory_order_relaxed); }
  115. inline uint64_t sum() const { return sum_.load(std::memory_order_relaxed); }
  116. inline uint64_t sum_squares() const {
  117. return sum_squares_.load(std::memory_order_relaxed);
  118. }
  119. inline uint64_t bucket_at(size_t b) const {
  120. return buckets_[b].load(std::memory_order_relaxed);
  121. }
  122. double Median() const;
  123. double Percentile(double p) const;
  124. double Average() const;
  125. double StandardDeviation() const;
  126. void Data(HistogramData* const data) const;
  127. std::string ToString() const;
  128. // To be able to use HistogramStat as thread local variable, it
  129. // cannot have dynamic allocated member. That's why we're
  130. // using manually values from BucketMapper
  131. std::atomic_uint_fast64_t min_;
  132. std::atomic_uint_fast64_t max_;
  133. std::atomic_uint_fast64_t num_;
  134. std::atomic_uint_fast64_t sum_;
  135. std::atomic_uint_fast64_t sum_squares_;
  136. std::atomic_uint_fast64_t buckets_[109]; // 109==BucketMapper::BucketCount()
  137. const uint64_t num_buckets_;
  138. };
  139. class Histogram {
  140. public:
  141. Histogram() {}
  142. virtual ~Histogram(){};
  143. virtual void Clear() = 0;
  144. virtual bool Empty() const = 0;
  145. virtual void Add(uint64_t value) = 0;
  146. virtual void Merge(const Histogram&) = 0;
  147. virtual std::string ToString() const = 0;
  148. virtual const char* Name() const = 0;
  149. virtual uint64_t min() const = 0;
  150. virtual uint64_t max() const = 0;
  151. virtual uint64_t num() const = 0;
  152. virtual double Median() const = 0;
  153. virtual double Percentile(double p) const = 0;
  154. virtual double Average() const = 0;
  155. virtual double StandardDeviation() const = 0;
  156. virtual void Data(HistogramData* const data) const = 0;
  157. };
  158. class HistogramImpl : public Histogram {
  159. public:
  160. HistogramImpl() { Clear(); }
  161. HistogramImpl(const HistogramImpl&) = delete;
  162. HistogramImpl& operator=(const HistogramImpl&) = delete;
  163. virtual void Clear() override;
  164. virtual bool Empty() const override;
  165. virtual void Add(uint64_t value) override;
  166. virtual void Merge(const Histogram& other) override;
  167. void Merge(const HistogramImpl& other);
  168. virtual std::string ToString() const override;
  169. virtual const char* Name() const override { return "HistogramImpl"; }
  170. virtual uint64_t min() const override { return stats_.min(); }
  171. virtual uint64_t max() const override { return stats_.max(); }
  172. virtual uint64_t num() const override { return stats_.num(); }
  173. virtual double Median() const override;
  174. virtual double Percentile(double p) const override;
  175. virtual double Average() const override;
  176. virtual double StandardDeviation() const override;
  177. virtual void Data(HistogramData* const data) const override;
  178. virtual ~HistogramImpl() {}
  179. private:
  180. HistogramStat stats_;
  181. std::mutex mutex_;
  182. };
  183. } // namespace wwsearch