Coverage Report

Created: 2026-08-14 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/monitoring/statistics_impl.h
Line
Count
Source
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
#pragma once
7
#include <atomic>
8
#include <map>
9
#include <string>
10
#include <vector>
11
12
#include "monitoring/histogram.h"
13
#include "port/likely.h"
14
#include "port/port.h"
15
#include "rocksdb/statistics.h"
16
#include "util/core_local.h"
17
#include "util/mutexlock.h"
18
19
#ifdef __clang__
20
#define ROCKSDB_FIELD_UNUSED __attribute__((__unused__))
21
#else
22
#define ROCKSDB_FIELD_UNUSED
23
#endif  // __clang__
24
25
#ifndef STRINGIFY
26
#define STRINGIFY(x) #x
27
#define TOSTRING(x) STRINGIFY(x)
28
#endif
29
30
namespace ROCKSDB_NAMESPACE {
31
32
enum TickersInternal : uint32_t {
33
  INTERNAL_TICKER_ENUM_START = TICKER_ENUM_MAX,
34
  INTERNAL_TICKER_ENUM_MAX
35
};
36
37
enum HistogramsInternal : uint32_t {
38
  INTERNAL_HISTOGRAM_START = HISTOGRAM_ENUM_MAX,
39
  INTERNAL_HISTOGRAM_ENUM_MAX
40
};
41
42
class StatisticsImpl : public Statistics {
43
 public:
44
  StatisticsImpl(std::shared_ptr<Statistics> stats);
45
  virtual ~StatisticsImpl();
46
0
  const char* Name() const override { return kClassName(); }
47
0
  static const char* kClassName() { return "BasicStatistics"; }
48
49
  uint64_t getTickerCount(uint32_t ticker_type) const override;
50
  void histogramData(uint32_t histogram_type,
51
                     HistogramData* const data) const override;
52
  std::string getHistogramString(uint32_t histogram_type) const override;
53
54
  void setTickerCount(uint32_t ticker_type, uint64_t count) override;
55
  uint64_t getAndResetTickerCount(uint32_t ticker_type) override;
56
  void recordTick(uint32_t ticker_type, uint64_t count) override;
57
  // The function is implemented for now for backward compatibility reason.
58
  // In case a user explictly calls it, for example, they may have a wrapped
59
  // Statistics object, passing the call to recordTick() into here, nothing
60
  // will break.
61
0
  void measureTime(uint32_t histogramType, uint64_t time) override {
62
0
    recordInHistogram(histogramType, time);
63
0
  }
64
  void recordInHistogram(uint32_t histogram_type, uint64_t value) override;
65
66
  Status Reset() override;
67
  std::string ToString() const override;
68
  bool getTickerMap(std::map<std::string, uint64_t>*) const override;
69
  bool HistEnabledForType(uint32_t type) const override;
70
71
0
  const Customizable* Inner() const override { return stats_.get(); }
72
73
 private:
74
  // If non-nullptr, forwards updates to the object pointed to by `stats_`.
75
  std::shared_ptr<Statistics> stats_;
76
  // Synchronizes anything that operates across other cores' local data,
77
  // such that operations like Reset() can be performed atomically.
78
  mutable port::Mutex aggregate_lock_;
79
80
  // The ticker/histogram data are stored in this structure, which we will store
81
  // per-core. It is cache-aligned, so tickers/histograms belonging to different
82
  // cores can never share the same cache line.
83
  //
84
  // Alignment attributes expand to nothing depending on the platform
85
  struct ALIGN_AS(CACHE_LINE_SIZE) StatisticsData {
86
    std::atomic_uint_fast64_t tickers_[INTERNAL_TICKER_ENUM_MAX] = {{0}};
87
    HistogramImpl histograms_[INTERNAL_HISTOGRAM_ENUM_MAX];
88
#ifndef HAVE_ALIGNED_NEW
89
    char
90
        padding[(CACHE_LINE_SIZE -
91
                 (INTERNAL_TICKER_ENUM_MAX * sizeof(std::atomic_uint_fast64_t) +
92
                  INTERNAL_HISTOGRAM_ENUM_MAX * sizeof(HistogramImpl)) %
93
                     CACHE_LINE_SIZE)] ROCKSDB_FIELD_UNUSED;
94
#endif
95
0
    void* operator new(size_t s) { return port::cacheline_aligned_alloc(s); }
96
0
    void* operator new[](size_t s) { return port::cacheline_aligned_alloc(s); }
97
0
    void operator delete(void* p) { port::cacheline_aligned_free(p); }
98
0
    void operator delete[](void* p) { port::cacheline_aligned_free(p); }
99
  };
100
101
#ifndef TEST_CACHE_LINE_SIZE
102
  static_assert(sizeof(StatisticsData) % CACHE_LINE_SIZE == 0,
103
                "Expected " TOSTRING(CACHE_LINE_SIZE) "-byte aligned");
104
#endif
105
106
  CoreLocalArray<StatisticsData> per_core_stats_;
107
108
  uint64_t getTickerCountLocked(uint32_t ticker_type) const;
109
  std::unique_ptr<HistogramImpl> getHistogramImplLocked(
110
      uint32_t histogram_type) const;
111
  void setTickerCountLocked(uint32_t ticker_type, uint64_t count);
112
};
113
114
// Utility functions
115
inline void RecordInHistogram(Statistics* statistics, uint32_t histogram_type,
116
980k
                              uint64_t value) {
117
980k
  if (statistics) {
118
0
    statistics->recordInHistogram(histogram_type, value);
119
0
  }
120
980k
}
121
122
inline void RecordTimeToHistogram(Statistics* statistics,
123
12.4k
                                  uint32_t histogram_type, uint64_t value) {
124
12.4k
  if (statistics) {
125
0
    statistics->reportTimeToHistogram(histogram_type, value);
126
0
  }
127
12.4k
}
128
129
inline void RecordTick(Statistics* statistics, uint32_t ticker_type,
130
6.29M
                       uint64_t count = 1) {
131
6.29M
  if (statistics) {
132
0
    statistics->recordTick(ticker_type, count);
133
0
  }
134
6.29M
}
135
136
inline void SetTickerCount(Statistics* statistics, uint32_t ticker_type,
137
0
                           uint64_t count) {
138
0
  if (statistics) {
139
0
    statistics->setTickerCount(ticker_type, count);
140
0
  }
141
0
}
142
143
}  // namespace ROCKSDB_NAMESPACE