File: statistics_impl.h

package info (click to toggle)
rocksdb 9.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 46,052 kB
  • sloc: cpp: 500,768; java: 42,992; ansic: 9,789; python: 8,373; perl: 5,822; sh: 4,921; makefile: 2,386; asm: 550; xml: 342
file content (143 lines) | stat: -rw-r--r-- 5,118 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//  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).
//
#pragma once
#include <atomic>
#include <map>
#include <string>
#include <vector>

#include "monitoring/histogram.h"
#include "port/likely.h"
#include "port/port.h"
#include "rocksdb/statistics.h"
#include "util/core_local.h"
#include "util/mutexlock.h"

#ifdef __clang__
#define ROCKSDB_FIELD_UNUSED __attribute__((__unused__))
#else
#define ROCKSDB_FIELD_UNUSED
#endif  // __clang__

#ifndef STRINGIFY
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#endif

namespace ROCKSDB_NAMESPACE {

enum TickersInternal : uint32_t {
  INTERNAL_TICKER_ENUM_START = TICKER_ENUM_MAX,
  INTERNAL_TICKER_ENUM_MAX
};

enum HistogramsInternal : uint32_t {
  INTERNAL_HISTOGRAM_START = HISTOGRAM_ENUM_MAX,
  INTERNAL_HISTOGRAM_ENUM_MAX
};

class StatisticsImpl : public Statistics {
 public:
  StatisticsImpl(std::shared_ptr<Statistics> stats);
  virtual ~StatisticsImpl();
  const char* Name() const override { return kClassName(); }
  static const char* kClassName() { return "BasicStatistics"; }

  uint64_t getTickerCount(uint32_t ticker_type) const override;
  void histogramData(uint32_t histogram_type,
                     HistogramData* const data) const override;
  std::string getHistogramString(uint32_t histogram_type) const override;

  void setTickerCount(uint32_t ticker_type, uint64_t count) override;
  uint64_t getAndResetTickerCount(uint32_t ticker_type) override;
  void recordTick(uint32_t ticker_type, uint64_t count) override;
  // The function is implemented for now for backward compatibility reason.
  // In case a user explictly calls it, for example, they may have a wrapped
  // Statistics object, passing the call to recordTick() into here, nothing
  // will break.
  void measureTime(uint32_t histogramType, uint64_t time) override {
    recordInHistogram(histogramType, time);
  }
  void recordInHistogram(uint32_t histogram_type, uint64_t value) override;

  Status Reset() override;
  std::string ToString() const override;
  bool getTickerMap(std::map<std::string, uint64_t>*) const override;
  bool HistEnabledForType(uint32_t type) const override;

  const Customizable* Inner() const override { return stats_.get(); }

 private:
  // If non-nullptr, forwards updates to the object pointed to by `stats_`.
  std::shared_ptr<Statistics> stats_;
  // Synchronizes anything that operates across other cores' local data,
  // such that operations like Reset() can be performed atomically.
  mutable port::Mutex aggregate_lock_;

  // The ticker/histogram data are stored in this structure, which we will store
  // per-core. It is cache-aligned, so tickers/histograms belonging to different
  // cores can never share the same cache line.
  //
  // Alignment attributes expand to nothing depending on the platform
  struct ALIGN_AS(CACHE_LINE_SIZE) StatisticsData {
    std::atomic_uint_fast64_t tickers_[INTERNAL_TICKER_ENUM_MAX] = {{0}};
    HistogramImpl histograms_[INTERNAL_HISTOGRAM_ENUM_MAX];
#ifndef HAVE_ALIGNED_NEW
    char
        padding[(CACHE_LINE_SIZE -
                 (INTERNAL_TICKER_ENUM_MAX * sizeof(std::atomic_uint_fast64_t) +
                  INTERNAL_HISTOGRAM_ENUM_MAX * sizeof(HistogramImpl)) %
                     CACHE_LINE_SIZE)] ROCKSDB_FIELD_UNUSED;
#endif
    void* operator new(size_t s) { return port::cacheline_aligned_alloc(s); }
    void* operator new[](size_t s) { return port::cacheline_aligned_alloc(s); }
    void operator delete(void* p) { port::cacheline_aligned_free(p); }
    void operator delete[](void* p) { port::cacheline_aligned_free(p); }
  };

#ifndef TEST_CACHE_LINE_SIZE
  static_assert(sizeof(StatisticsData) % CACHE_LINE_SIZE == 0,
                "Expected " TOSTRING(CACHE_LINE_SIZE) "-byte aligned");
#endif

  CoreLocalArray<StatisticsData> per_core_stats_;

  uint64_t getTickerCountLocked(uint32_t ticker_type) const;
  std::unique_ptr<HistogramImpl> getHistogramImplLocked(
      uint32_t histogram_type) const;
  void setTickerCountLocked(uint32_t ticker_type, uint64_t count);
};

// Utility functions
inline void RecordInHistogram(Statistics* statistics, uint32_t histogram_type,
                              uint64_t value) {
  if (statistics) {
    statistics->recordInHistogram(histogram_type, value);
  }
}

inline void RecordTimeToHistogram(Statistics* statistics,
                                  uint32_t histogram_type, uint64_t value) {
  if (statistics) {
    statistics->reportTimeToHistogram(histogram_type, value);
  }
}

inline void RecordTick(Statistics* statistics, uint32_t ticker_type,
                       uint64_t count = 1) {
  if (statistics) {
    statistics->recordTick(ticker_type, count);
  }
}

inline void SetTickerCount(Statistics* statistics, uint32_t ticker_type,
                           uint64_t count) {
  if (statistics) {
    statistics->setTickerCount(ticker_type, count);
  }
}

}  // namespace ROCKSDB_NAMESPACE