/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_ |