Coverage Report

Created: 2026-01-21 08:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/src/histogram.h
Line
Count
Source
1
#ifndef SRC_HISTOGRAM_H_
2
#define SRC_HISTOGRAM_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include <hdr/hdr_histogram.h>
7
#include "base_object.h"
8
#include "memory_tracker.h"
9
#include "node_messaging.h"
10
#include "util.h"
11
#include "uv.h"
12
#include "v8.h"
13
14
#include <functional>
15
#include <limits>
16
#include <map>
17
#include <string>
18
19
namespace node {
20
21
class ExternalReferenceRegistry;
22
23
constexpr int kDefaultHistogramFigures = 3;
24
25
class Histogram : public MemoryRetainer {
26
 public:
27
  struct Options {
28
    int64_t lowest = 1;
29
    int64_t highest = std::numeric_limits<int64_t>::max();
30
    int figures = kDefaultHistogramFigures;
31
  };
32
33
  explicit Histogram(const Options& options);
34
0
  virtual ~Histogram() = default;
35
36
  inline bool Record(int64_t value);
37
  inline void Reset();
38
  inline int64_t Min() const;
39
  inline int64_t Max() const;
40
  inline double Mean() const;
41
  inline double Stddev() const;
42
  inline int64_t Percentile(double percentile) const;
43
0
  inline size_t Exceeds() const { return exceeds_; }
44
  inline size_t Count() const;
45
46
  inline uint64_t RecordDelta();
47
48
  inline double Add(const Histogram& other);
49
50
  // Iterator is a function type that takes two doubles as argument, one for
51
  // percentile and one for the value at that percentile.
52
  template <typename Iterator>
53
  inline void Percentiles(Iterator&& fn);
54
55
  inline size_t GetMemorySize() const;
56
57
  void MemoryInfo(MemoryTracker* tracker) const override;
58
  SET_MEMORY_INFO_NAME(Histogram)
59
  SET_SELF_SIZE(Histogram)
60
61
 private:
62
  using HistogramPointer = DeleteFnPtr<hdr_histogram, hdr_close>;
63
  HistogramPointer histogram_;
64
  uint64_t prev_ = 0;
65
  size_t exceeds_ = 0;
66
  size_t count_ = 0;
67
  Mutex mutex_;
68
};
69
70
class HistogramImpl {
71
 public:
72
  enum InternalFields {
73
    kSlot = BaseObject::kSlot,
74
    kImplField = BaseObject::kInternalFieldCount,
75
    kInternalFieldCount
76
  };
77
78
  explicit HistogramImpl(
79
      const Histogram::Options& options = Histogram::Options {});
80
  explicit HistogramImpl(std::shared_ptr<Histogram> histogram);
81
82
0
  Histogram* operator->() { return histogram_.get(); }
83
84
0
  const std::shared_ptr<Histogram>& histogram() const { return histogram_; }
85
86
  static void DoReset(const v8::FunctionCallbackInfo<v8::Value>& args);
87
  static void GetCountBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
88
  static void GetMinBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
89
  static void GetMaxBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
90
  static void GetExceedsBigInt(const v8::FunctionCallbackInfo<v8::Value>& args);
91
  static void GetCount(const v8::FunctionCallbackInfo<v8::Value>& args);
92
  static void GetMin(const v8::FunctionCallbackInfo<v8::Value>& args);
93
  static void GetMax(const v8::FunctionCallbackInfo<v8::Value>& args);
94
  static void GetMean(const v8::FunctionCallbackInfo<v8::Value>& args);
95
  static void GetExceeds(const v8::FunctionCallbackInfo<v8::Value>& args);
96
  static void GetStddev(const v8::FunctionCallbackInfo<v8::Value>& args);
97
  static void GetPercentile(const v8::FunctionCallbackInfo<v8::Value>& args);
98
  static void GetPercentileBigInt(
99
      const v8::FunctionCallbackInfo<v8::Value>& args);
100
  static void GetPercentiles(const v8::FunctionCallbackInfo<v8::Value>& args);
101
  static void GetPercentilesBigInt(
102
      const v8::FunctionCallbackInfo<v8::Value>& args);
103
104
  static void FastReset(v8::Local<v8::Value> receiver);
105
  static double FastGetCount(v8::Local<v8::Value> receiver);
106
  static double FastGetMin(v8::Local<v8::Value> receiver);
107
  static double FastGetMax(v8::Local<v8::Value> receiver);
108
  static double FastGetMean(v8::Local<v8::Value> receiver);
109
  static double FastGetExceeds(v8::Local<v8::Value> receiver);
110
  static double FastGetStddev(v8::Local<v8::Value> receiver);
111
  static double FastGetPercentile(v8::Local<v8::Value> receiver,
112
                                  const double percentile);
113
114
  static void AddMethods(v8::Isolate* isolate,
115
                         v8::Local<v8::FunctionTemplate> tmpl);
116
117
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
118
119
  static HistogramImpl* FromJSObject(v8::Local<v8::Value> value);
120
121
 private:
122
  std::shared_ptr<Histogram> histogram_;
123
124
  static v8::CFunction fast_reset_;
125
  static v8::CFunction fast_get_count_;
126
  static v8::CFunction fast_get_min_;
127
  static v8::CFunction fast_get_max_;
128
  static v8::CFunction fast_get_mean_;
129
  static v8::CFunction fast_get_exceeds_;
130
  static v8::CFunction fast_get_stddev_;
131
  static v8::CFunction fast_get_percentile_;
132
};
133
134
class HistogramBase final : public BaseObject, public HistogramImpl {
135
 public:
136
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
137
      IsolateData* isolate_data);
138
  static void Initialize(IsolateData* isolate_data,
139
                         v8::Local<v8::ObjectTemplate> target);
140
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
141
142
  static BaseObjectPtr<HistogramBase> Create(
143
      Environment* env,
144
      const Histogram::Options& options = Histogram::Options {});
145
146
  static BaseObjectPtr<HistogramBase> Create(
147
      Environment* env,
148
      std::shared_ptr<Histogram> histogram);
149
150
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
151
152
  void MemoryInfo(MemoryTracker* tracker) const override;
153
  SET_MEMORY_INFO_NAME(HistogramBase)
154
  SET_SELF_SIZE(HistogramBase)
155
156
  static void Record(const v8::FunctionCallbackInfo<v8::Value>& args);
157
  static void RecordDelta(const v8::FunctionCallbackInfo<v8::Value>& args);
158
  static void Add(const v8::FunctionCallbackInfo<v8::Value>& args);
159
160
  static void FastRecord(v8::Local<v8::Value> receiver, const int64_t value);
161
  static void FastRecordDelta(v8::Local<v8::Value> receiver);
162
163
  HistogramBase(
164
      Environment* env,
165
      v8::Local<v8::Object> wrap,
166
      const Histogram::Options& options = Histogram::Options {});
167
168
  HistogramBase(
169
      Environment* env,
170
      v8::Local<v8::Object> wrap,
171
      std::shared_ptr<Histogram> histogram);
172
173
0
  BaseObject::TransferMode GetTransferMode() const override {
174
0
    return TransferMode::kCloneable;
175
0
  }
176
  std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
177
178
  class HistogramTransferData : public worker::TransferData {
179
   public:
180
    explicit HistogramTransferData(const HistogramBase* histogram)
181
0
        : histogram_(histogram->histogram()) {}
182
183
    explicit HistogramTransferData(std::shared_ptr<Histogram> histogram)
184
0
        : histogram_(std::move(histogram)) {}
185
186
    BaseObjectPtr<BaseObject> Deserialize(
187
        Environment* env,
188
        v8::Local<v8::Context> context,
189
        std::unique_ptr<worker::TransferData> self) override;
190
191
    void MemoryInfo(MemoryTracker* tracker) const override;
192
    SET_MEMORY_INFO_NAME(HistogramTransferData)
193
    SET_SELF_SIZE(HistogramTransferData)
194
195
   private:
196
    std::shared_ptr<Histogram> histogram_;
197
  };
198
199
 private:
200
  static v8::CFunction fast_record_;
201
  static v8::CFunction fast_record_delta_;
202
};
203
204
class IntervalHistogram final : public HandleWrap, public HistogramImpl {
205
 public:
206
  enum class StartFlags {
207
    NONE,
208
    RESET
209
  };
210
211
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
212
213
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
214
      Environment* env);
215
216
  static BaseObjectPtr<IntervalHistogram> Create(
217
      Environment* env,
218
      int32_t interval,
219
      std::function<void(Histogram&)> on_interval,
220
      const Histogram::Options& options);
221
222
  IntervalHistogram(
223
      Environment* env,
224
      v8::Local<v8::Object> wrap,
225
      AsyncWrap::ProviderType type,
226
      int32_t interval,
227
      std::function<void(Histogram&)> on_interval,
228
      const Histogram::Options& options = Histogram::Options {});
229
230
  static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
231
  static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
232
233
  static void FastStart(v8::Local<v8::Value> receiver, bool reset);
234
  static void FastStop(v8::Local<v8::Value> receiver);
235
236
0
  BaseObject::TransferMode GetTransferMode() const override {
237
0
    return TransferMode::kCloneable;
238
0
  }
239
  std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
240
241
  void MemoryInfo(MemoryTracker* tracker) const override;
242
  SET_MEMORY_INFO_NAME(IntervalHistogram)
243
  SET_SELF_SIZE(IntervalHistogram)
244
245
 private:
246
  static void TimerCB(uv_timer_t* handle);
247
  void OnStart(StartFlags flags = StartFlags::RESET);
248
  void OnStop();
249
250
  bool enabled_ = false;
251
  int32_t interval_ = 0;
252
  std::function<void(Histogram&)> on_interval_;
253
  uv_timer_t timer_;
254
255
  static v8::CFunction fast_start_;
256
  static v8::CFunction fast_stop_;
257
};
258
259
}  // namespace node
260
261
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
262
263
#endif  // SRC_HISTOGRAM_H_