1 #include "histogram.h" // NOLINT(build/include_inline)
2 #include "base_object-inl.h"
3 #include "histogram-inl.h"
4 #include "memory_tracker-inl.h"
5 #include "node_errors.h"
6 #include "node_external_reference.h"
7
8 namespace node {
9
10 using v8::BigInt;
11 using v8::FunctionCallbackInfo;
12 using v8::FunctionTemplate;
13 using v8::Integer;
14 using v8::Isolate;
15 using v8::Local;
16 using v8::Map;
17 using v8::Number;
18 using v8::Object;
19 using v8::String;
20 using v8::Uint32;
21 using v8::Value;
22
Histogram(const Options& options)23 Histogram::Histogram(const Options& options) {
24 hdr_histogram* histogram;
25 CHECK_EQ(0, hdr_init(options.lowest,
26 options.highest,
27 options.figures,
28 &histogram));
29 histogram_.reset(histogram);
30 }
31
MemoryInfo(MemoryTracker* tracker) const32 void Histogram::MemoryInfo(MemoryTracker* tracker) const {
33 tracker->TrackFieldWithSize("histogram", GetMemorySize());
34 }
35
HistogramImpl(const Histogram::Options& options)36 HistogramImpl::HistogramImpl(const Histogram::Options& options)
37 : histogram_(new Histogram(options)) {}
38
HistogramImpl(std::shared_ptr<Histogram> histogram)39 HistogramImpl::HistogramImpl(std::shared_ptr<Histogram> histogram)
40 : histogram_(std::move(histogram)) {}
41
HistogramBase( Environment* env, Local<Object> wrap, const Histogram::Options& options)42 HistogramBase::HistogramBase(
43 Environment* env,
44 Local<Object> wrap,
45 const Histogram::Options& options)
46 : BaseObject(env, wrap),
47 HistogramImpl(options) {
48 MakeWeak();
49 }
50
HistogramBase( Environment* env, Local<Object> wrap, std::shared_ptr<Histogram> histogram)51 HistogramBase::HistogramBase(
52 Environment* env,
53 Local<Object> wrap,
54 std::shared_ptr<Histogram> histogram)
55 : BaseObject(env, wrap),
56 HistogramImpl(std::move(histogram)) {
57 MakeWeak();
58 }
59
MemoryInfo(MemoryTracker* tracker) const60 void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
61 tracker->TrackField("histogram", histogram());
62 }
63
GetCount(const v8::FunctionCallbackInfo<v8::Value>& args)64 void HistogramBase::GetCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
65 HistogramBase* histogram;
66 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
67 double value = static_cast<double>((*histogram)->Count());
68 args.GetReturnValue().Set(value);
69 }
70
GetCountBigInt( const v8::FunctionCallbackInfo<v8::Value>& args)71 void HistogramBase::GetCountBigInt(
72 const v8::FunctionCallbackInfo<v8::Value>& args) {
73 Environment* env = Environment::GetCurrent(args);
74 HistogramBase* histogram;
75 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
76 args.GetReturnValue().Set(
77 BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count()));
78 }
79
GetMin(const FunctionCallbackInfo<Value>& args)80 void HistogramBase::GetMin(const FunctionCallbackInfo<Value>& args) {
81 HistogramBase* histogram;
82 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
83 double value = static_cast<double>((*histogram)->Min());
84 args.GetReturnValue().Set(value);
85 }
86
GetMinBigInt(const FunctionCallbackInfo<Value>& args)87 void HistogramBase::GetMinBigInt(const FunctionCallbackInfo<Value>& args) {
88 Environment* env = Environment::GetCurrent(args);
89 HistogramBase* histogram;
90 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
91 args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
92 }
93
GetMax(const FunctionCallbackInfo<Value>& args)94 void HistogramBase::GetMax(const FunctionCallbackInfo<Value>& args) {
95 HistogramBase* histogram;
96 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
97 double value = static_cast<double>((*histogram)->Max());
98 args.GetReturnValue().Set(value);
99 }
100
GetMaxBigInt(const FunctionCallbackInfo<Value>& args)101 void HistogramBase::GetMaxBigInt(const FunctionCallbackInfo<Value>& args) {
102 Environment* env = Environment::GetCurrent(args);
103 HistogramBase* histogram;
104 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
105 args.GetReturnValue().Set(
106 BigInt::New(env->isolate(), (*histogram)->Max()));
107 }
108
GetMean(const FunctionCallbackInfo<Value>& args)109 void HistogramBase::GetMean(const FunctionCallbackInfo<Value>& args) {
110 HistogramBase* histogram;
111 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
112 args.GetReturnValue().Set((*histogram)->Mean());
113 }
114
GetExceeds(const FunctionCallbackInfo<Value>& args)115 void HistogramBase::GetExceeds(const FunctionCallbackInfo<Value>& args) {
116 HistogramBase* histogram;
117 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
118 double value = static_cast<double>((*histogram)->Exceeds());
119 args.GetReturnValue().Set(value);
120 }
121
GetExceedsBigInt(const FunctionCallbackInfo<Value>& args)122 void HistogramBase::GetExceedsBigInt(const FunctionCallbackInfo<Value>& args) {
123 Environment* env = Environment::GetCurrent(args);
124 HistogramBase* histogram;
125 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
126 args.GetReturnValue().Set(
127 BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Exceeds()));
128 }
129
GetStddev(const FunctionCallbackInfo<Value>& args)130 void HistogramBase::GetStddev(const FunctionCallbackInfo<Value>& args) {
131 HistogramBase* histogram;
132 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
133 args.GetReturnValue().Set((*histogram)->Stddev());
134 }
135
GetPercentile(const FunctionCallbackInfo<Value>& args)136 void HistogramBase::GetPercentile(const FunctionCallbackInfo<Value>& args) {
137 HistogramBase* histogram;
138 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
139 CHECK(args[0]->IsNumber());
140 double percentile = args[0].As<Number>()->Value();
141 double value = static_cast<double>((*histogram)->Percentile(percentile));
142 args.GetReturnValue().Set(value);
143 }
144
GetPercentileBigInt( const FunctionCallbackInfo<Value>& args)145 void HistogramBase::GetPercentileBigInt(
146 const FunctionCallbackInfo<Value>& args) {
147 Environment* env = Environment::GetCurrent(args);
148 HistogramBase* histogram;
149 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
150 CHECK(args[0]->IsNumber());
151 double percentile = args[0].As<Number>()->Value();
152 int64_t value = (*histogram)->Percentile(percentile);
153 args.GetReturnValue().Set(BigInt::New(env->isolate(), value));
154 }
155
GetPercentiles(const FunctionCallbackInfo<Value>& args)156 void HistogramBase::GetPercentiles(const FunctionCallbackInfo<Value>& args) {
157 Environment* env = Environment::GetCurrent(args);
158 HistogramBase* histogram;
159 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
160 CHECK(args[0]->IsMap());
161 Local<Map> map = args[0].As<Map>();
162 (*histogram)->Percentiles([map, env](double key, int64_t value) {
163 USE(map->Set(
164 env->context(),
165 Number::New(env->isolate(), key),
166 Number::New(env->isolate(), static_cast<double>(value))));
167 });
168 }
169
GetPercentilesBigInt( const FunctionCallbackInfo<Value>& args)170 void HistogramBase::GetPercentilesBigInt(
171 const FunctionCallbackInfo<Value>& args) {
172 Environment* env = Environment::GetCurrent(args);
173 HistogramBase* histogram;
174 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
175 CHECK(args[0]->IsMap());
176 Local<Map> map = args[0].As<Map>();
177 (*histogram)->Percentiles([map, env](double key, int64_t value) {
178 USE(map->Set(
179 env->context(),
180 Number::New(env->isolate(), key),
181 BigInt::New(env->isolate(), value)));
182 });
183 }
184
DoReset(const FunctionCallbackInfo<Value>& args)185 void HistogramBase::DoReset(const FunctionCallbackInfo<Value>& args) {
186 HistogramBase* histogram;
187 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
188 (*histogram)->Reset();
189 }
190
RecordDelta(const FunctionCallbackInfo<Value>& args)191 void HistogramBase::RecordDelta(const FunctionCallbackInfo<Value>& args) {
192 HistogramBase* histogram;
193 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
194 (*histogram)->RecordDelta();
195 }
196
Record(const FunctionCallbackInfo<Value>& args)197 void HistogramBase::Record(const FunctionCallbackInfo<Value>& args) {
198 Environment* env = Environment::GetCurrent(args);
199 CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
200 bool lossless = true;
201 int64_t value = args[0]->IsBigInt()
202 ? args[0].As<BigInt>()->Int64Value(&lossless)
203 : static_cast<int64_t>(args[0].As<Number>()->Value());
204 if (!lossless || value < 1)
205 return THROW_ERR_OUT_OF_RANGE(env, "value is out of range");
206 HistogramBase* histogram;
207 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
208 (*histogram)->Record(value);
209 }
210
Add(const FunctionCallbackInfo<Value>& args)211 void HistogramBase::Add(const FunctionCallbackInfo<Value>& args) {
212 Environment* env = Environment::GetCurrent(args);
213 HistogramBase* histogram;
214 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
215
216 CHECK(GetConstructorTemplate(env)->HasInstance(args[0]));
217 HistogramBase* other;
218 ASSIGN_OR_RETURN_UNWRAP(&other, args[0]);
219
220 double count = (*histogram)->Add(*(other->histogram()));
221 args.GetReturnValue().Set(count);
222 }
223
Create( Environment* env, const Histogram::Options& options)224 BaseObjectPtr<HistogramBase> HistogramBase::Create(
225 Environment* env,
226 const Histogram::Options& options) {
227 Local<Object> obj;
228 if (!GetConstructorTemplate(env)
229 ->InstanceTemplate()
230 ->NewInstance(env->context()).ToLocal(&obj)) {
231 return BaseObjectPtr<HistogramBase>();
232 }
233
234 return MakeBaseObject<HistogramBase>(env, obj, options);
235 }
236
Create( Environment* env, std::shared_ptr<Histogram> histogram)237 BaseObjectPtr<HistogramBase> HistogramBase::Create(
238 Environment* env,
239 std::shared_ptr<Histogram> histogram) {
240 Local<Object> obj;
241 if (!GetConstructorTemplate(env)
242 ->InstanceTemplate()
243 ->NewInstance(env->context()).ToLocal(&obj)) {
244 return BaseObjectPtr<HistogramBase>();
245 }
246 return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
247 }
248
New(const FunctionCallbackInfo<Value>& args)249 void HistogramBase::New(const FunctionCallbackInfo<Value>& args) {
250 CHECK(args.IsConstructCall());
251 Environment* env = Environment::GetCurrent(args);
252
253 CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
254 CHECK_IMPLIES(!args[1]->IsNumber(), args[1]->IsBigInt());
255 CHECK(args[2]->IsUint32());
256
257 int64_t lowest = 1;
258 int64_t highest = std::numeric_limits<int64_t>::max();
259
260 bool lossless_ignored;
261
262 if (args[0]->IsNumber()) {
263 lowest = args[0].As<Integer>()->Value();
264 } else if (args[0]->IsBigInt()) {
265 lowest = args[0].As<BigInt>()->Int64Value(&lossless_ignored);
266 }
267
268 if (args[1]->IsNumber()) {
269 highest = args[1].As<Integer>()->Value();
270 } else if (args[1]->IsBigInt()) {
271 highest = args[1].As<BigInt>()->Int64Value(&lossless_ignored);
272 }
273
274 int32_t figures = args[2].As<Uint32>()->Value();
275 new HistogramBase(env, args.This(), Histogram::Options {
276 lowest, highest, figures
277 });
278 }
279
GetConstructorTemplate( Environment* env)280 Local<FunctionTemplate> HistogramBase::GetConstructorTemplate(
281 Environment* env) {
282 Local<FunctionTemplate> tmpl = env->histogram_ctor_template();
283 if (tmpl.IsEmpty()) {
284 Isolate* isolate = env->isolate();
285 tmpl = NewFunctionTemplate(isolate, New);
286 Local<String> classname =
287 FIXED_ONE_BYTE_STRING(env->isolate(), "Histogram");
288 tmpl->SetClassName(classname);
289 tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
290
291 tmpl->InstanceTemplate()->SetInternalFieldCount(
292 HistogramBase::kInternalFieldCount);
293 SetProtoMethodNoSideEffect(isolate, tmpl, "count", GetCount);
294 SetProtoMethodNoSideEffect(isolate, tmpl, "countBigInt", GetCountBigInt);
295 SetProtoMethodNoSideEffect(isolate, tmpl, "exceeds", GetExceeds);
296 SetProtoMethodNoSideEffect(
297 isolate, tmpl, "exceedsBigInt", GetExceedsBigInt);
298 SetProtoMethodNoSideEffect(isolate, tmpl, "min", GetMin);
299 SetProtoMethodNoSideEffect(isolate, tmpl, "minBigInt", GetMinBigInt);
300 SetProtoMethodNoSideEffect(isolate, tmpl, "max", GetMax);
301 SetProtoMethodNoSideEffect(isolate, tmpl, "maxBigInt", GetMaxBigInt);
302 SetProtoMethodNoSideEffect(isolate, tmpl, "mean", GetMean);
303 SetProtoMethodNoSideEffect(isolate, tmpl, "stddev", GetStddev);
304 SetProtoMethodNoSideEffect(isolate, tmpl, "percentile", GetPercentile);
305 SetProtoMethodNoSideEffect(
306 isolate, tmpl, "percentileBigInt", GetPercentileBigInt);
307 SetProtoMethodNoSideEffect(isolate, tmpl, "percentiles", GetPercentiles);
308 SetProtoMethodNoSideEffect(
309 isolate, tmpl, "percentilesBigInt", GetPercentilesBigInt);
310 SetProtoMethod(isolate, tmpl, "reset", DoReset);
311 SetProtoMethod(isolate, tmpl, "record", Record);
312 SetProtoMethod(isolate, tmpl, "recordDelta", RecordDelta);
313 SetProtoMethod(isolate, tmpl, "add", Add);
314 env->set_histogram_ctor_template(tmpl);
315 }
316 return tmpl;
317 }
318
RegisterExternalReferences( ExternalReferenceRegistry* registry)319 void HistogramBase::RegisterExternalReferences(
320 ExternalReferenceRegistry* registry) {
321 registry->Register(New);
322 registry->Register(GetCount);
323 registry->Register(GetCountBigInt);
324 registry->Register(GetExceeds);
325 registry->Register(GetExceedsBigInt);
326 registry->Register(GetMin);
327 registry->Register(GetMinBigInt);
328 registry->Register(GetMax);
329 registry->Register(GetMaxBigInt);
330 registry->Register(GetMean);
331 registry->Register(GetStddev);
332 registry->Register(GetPercentile);
333 registry->Register(GetPercentileBigInt);
334 registry->Register(GetPercentiles);
335 registry->Register(GetPercentilesBigInt);
336 registry->Register(DoReset);
337 registry->Register(Record);
338 registry->Register(RecordDelta);
339 registry->Register(Add);
340 }
341
Initialize(Environment* env, Local<Object> target)342 void HistogramBase::Initialize(Environment* env, Local<Object> target) {
343 SetConstructorFunction(env->context(),
344 target,
345 "Histogram",
346 GetConstructorTemplate(env),
347 SetConstructorFunctionFlag::NONE);
348 }
349
Deserialize( Environment* env, v8::Local<v8::Context> context, std::unique_ptr<worker::TransferData> self)350 BaseObjectPtr<BaseObject> HistogramBase::HistogramTransferData::Deserialize(
351 Environment* env,
352 v8::Local<v8::Context> context,
353 std::unique_ptr<worker::TransferData> self) {
354 return Create(env, std::move(histogram_));
355 }
356
CloneForMessaging() const357 std::unique_ptr<worker::TransferData> HistogramBase::CloneForMessaging() const {
358 return std::make_unique<HistogramTransferData>(this);
359 }
360
MemoryInfo( MemoryTracker* tracker) const361 void HistogramBase::HistogramTransferData::MemoryInfo(
362 MemoryTracker* tracker) const {
363 tracker->TrackField("histogram", histogram_);
364 }
365
GetConstructorTemplate( Environment* env)366 Local<FunctionTemplate> IntervalHistogram::GetConstructorTemplate(
367 Environment* env) {
368 Local<FunctionTemplate> tmpl = env->intervalhistogram_constructor_template();
369 if (tmpl.IsEmpty()) {
370 Isolate* isolate = env->isolate();
371 tmpl = NewFunctionTemplate(isolate, nullptr);
372 tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
373 tmpl->SetClassName(OneByteString(isolate, "Histogram"));
374 tmpl->InstanceTemplate()->SetInternalFieldCount(
375 HistogramBase::kInternalFieldCount);
376 SetProtoMethodNoSideEffect(isolate, tmpl, "count", GetCount);
377 SetProtoMethodNoSideEffect(isolate, tmpl, "countBigInt", GetCountBigInt);
378 SetProtoMethodNoSideEffect(isolate, tmpl, "exceeds", GetExceeds);
379 SetProtoMethodNoSideEffect(
380 isolate, tmpl, "exceedsBigInt", GetExceedsBigInt);
381 SetProtoMethodNoSideEffect(isolate, tmpl, "min", GetMin);
382 SetProtoMethodNoSideEffect(isolate, tmpl, "minBigInt", GetMinBigInt);
383 SetProtoMethodNoSideEffect(isolate, tmpl, "max", GetMax);
384 SetProtoMethodNoSideEffect(isolate, tmpl, "maxBigInt", GetMaxBigInt);
385 SetProtoMethodNoSideEffect(isolate, tmpl, "mean", GetMean);
386 SetProtoMethodNoSideEffect(isolate, tmpl, "stddev", GetStddev);
387 SetProtoMethodNoSideEffect(isolate, tmpl, "percentile", GetPercentile);
388 SetProtoMethodNoSideEffect(
389 isolate, tmpl, "percentileBigInt", GetPercentileBigInt);
390 SetProtoMethodNoSideEffect(isolate, tmpl, "percentiles", GetPercentiles);
391 SetProtoMethodNoSideEffect(
392 isolate, tmpl, "percentilesBigInt", GetPercentilesBigInt);
393 SetProtoMethod(isolate, tmpl, "reset", DoReset);
394 SetProtoMethod(isolate, tmpl, "start", Start);
395 SetProtoMethod(isolate, tmpl, "stop", Stop);
396 env->set_intervalhistogram_constructor_template(tmpl);
397 }
398 return tmpl;
399 }
400
RegisterExternalReferences( ExternalReferenceRegistry* registry)401 void IntervalHistogram::RegisterExternalReferences(
402 ExternalReferenceRegistry* registry) {
403 registry->Register(GetCount);
404 registry->Register(GetCountBigInt);
405 registry->Register(GetExceeds);
406 registry->Register(GetExceedsBigInt);
407 registry->Register(GetMin);
408 registry->Register(GetMinBigInt);
409 registry->Register(GetMax);
410 registry->Register(GetMaxBigInt);
411 registry->Register(GetMean);
412 registry->Register(GetStddev);
413 registry->Register(GetPercentile);
414 registry->Register(GetPercentileBigInt);
415 registry->Register(GetPercentiles);
416 registry->Register(GetPercentilesBigInt);
417 registry->Register(DoReset);
418 registry->Register(Start);
419 registry->Register(Stop);
420 }
421
IntervalHistogram( Environment* env, Local<Object> wrap, AsyncWrap::ProviderType type, int32_t interval, std::function<void(Histogram&)> on_interval, const Histogram::Options& options)422 IntervalHistogram::IntervalHistogram(
423 Environment* env,
424 Local<Object> wrap,
425 AsyncWrap::ProviderType type,
426 int32_t interval,
427 std::function<void(Histogram&)> on_interval,
428 const Histogram::Options& options)
429 : HandleWrap(
430 env,
431 wrap,
432 reinterpret_cast<uv_handle_t*>(&timer_),
433 type),
434 HistogramImpl(options),
435 interval_(interval),
436 on_interval_(std::move(on_interval)) {
437 MakeWeak();
438 uv_timer_init(env->event_loop(), &timer_);
439 }
440
Create( Environment* env, int32_t interval, std::function<void(Histogram&)> on_interval, const Histogram::Options& options)441 BaseObjectPtr<IntervalHistogram> IntervalHistogram::Create(
442 Environment* env,
443 int32_t interval,
444 std::function<void(Histogram&)> on_interval,
445 const Histogram::Options& options) {
446 Local<Object> obj;
447 if (!GetConstructorTemplate(env)
448 ->InstanceTemplate()
449 ->NewInstance(env->context()).ToLocal(&obj)) {
450 return BaseObjectPtr<IntervalHistogram>();
451 }
452
453 return MakeBaseObject<IntervalHistogram>(
454 env,
455 obj,
456 AsyncWrap::PROVIDER_ELDHISTOGRAM,
457 interval,
458 std::move(on_interval),
459 options);
460 }
461
TimerCB(uv_timer_t* handle)462 void IntervalHistogram::TimerCB(uv_timer_t* handle) {
463 IntervalHistogram* histogram =
464 ContainerOf(&IntervalHistogram::timer_, handle);
465
466 Histogram* h = histogram->histogram().get();
467
468 histogram->on_interval_(*h);
469 }
470
MemoryInfo(MemoryTracker* tracker) const471 void IntervalHistogram::MemoryInfo(MemoryTracker* tracker) const {
472 tracker->TrackField("histogram", histogram());
473 }
474
OnStart(StartFlags flags)475 void IntervalHistogram::OnStart(StartFlags flags) {
476 if (enabled_ || IsHandleClosing()) return;
477 enabled_ = true;
478 if (flags == StartFlags::RESET)
479 histogram()->Reset();
480 uv_timer_start(&timer_, TimerCB, interval_, interval_);
481 uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
482 }
483
OnStop()484 void IntervalHistogram::OnStop() {
485 if (!enabled_ || IsHandleClosing()) return;
486 enabled_ = false;
487 uv_timer_stop(&timer_);
488 }
489
Start(const FunctionCallbackInfo<Value>& args)490 void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
491 IntervalHistogram* histogram;
492 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
493 histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE);
494 }
495
Stop(const FunctionCallbackInfo<Value>& args)496 void IntervalHistogram::Stop(const FunctionCallbackInfo<Value>& args) {
497 IntervalHistogram* histogram;
498 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
499 histogram->OnStop();
500 }
501
GetCount(const FunctionCallbackInfo<Value>& args)502 void IntervalHistogram::GetCount(const FunctionCallbackInfo<Value>& args) {
503 IntervalHistogram* histogram;
504 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
505 double value = static_cast<double>((*histogram)->Count());
506 args.GetReturnValue().Set(value);
507 }
508
GetCountBigInt( const v8::FunctionCallbackInfo<v8::Value>& args)509 void IntervalHistogram::GetCountBigInt(
510 const v8::FunctionCallbackInfo<v8::Value>& args) {
511 Environment* env = Environment::GetCurrent(args);
512 IntervalHistogram* histogram;
513 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
514 args.GetReturnValue().Set(
515 BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count()));
516 }
517
GetMin(const FunctionCallbackInfo<Value>& args)518 void IntervalHistogram::GetMin(const FunctionCallbackInfo<Value>& args) {
519 IntervalHistogram* histogram;
520 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
521 double value = static_cast<double>((*histogram)->Min());
522 args.GetReturnValue().Set(value);
523 }
524
GetMinBigInt(const FunctionCallbackInfo<Value>& args)525 void IntervalHistogram::GetMinBigInt(const FunctionCallbackInfo<Value>& args) {
526 Environment* env = Environment::GetCurrent(args);
527 IntervalHistogram* histogram;
528 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
529 args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
530 }
531
GetMax(const FunctionCallbackInfo<Value>& args)532 void IntervalHistogram::GetMax(const FunctionCallbackInfo<Value>& args) {
533 IntervalHistogram* histogram;
534 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
535 double value = static_cast<double>((*histogram)->Max());
536 args.GetReturnValue().Set(value);
537 }
538
GetMaxBigInt(const FunctionCallbackInfo<Value>& args)539 void IntervalHistogram::GetMaxBigInt(const FunctionCallbackInfo<Value>& args) {
540 Environment* env = Environment::GetCurrent(args);
541 IntervalHistogram* histogram;
542 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
543 args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
544 }
545
GetMean(const FunctionCallbackInfo<Value>& args)546 void IntervalHistogram::GetMean(const FunctionCallbackInfo<Value>& args) {
547 IntervalHistogram* histogram;
548 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
549 args.GetReturnValue().Set((*histogram)->Mean());
550 }
551
GetExceeds(const FunctionCallbackInfo<Value>& args)552 void IntervalHistogram::GetExceeds(const FunctionCallbackInfo<Value>& args) {
553 IntervalHistogram* histogram;
554 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
555 double value = static_cast<double>((*histogram)->Exceeds());
556 args.GetReturnValue().Set(value);
557 }
558
GetExceedsBigInt( const FunctionCallbackInfo<Value>& args)559 void IntervalHistogram::GetExceedsBigInt(
560 const FunctionCallbackInfo<Value>& args) {
561 Environment* env = Environment::GetCurrent(args);
562 IntervalHistogram* histogram;
563 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
564 args.GetReturnValue().Set(
565 BigInt::New(env->isolate(), (*histogram)->Exceeds()));
566 }
567
GetStddev(const FunctionCallbackInfo<Value>& args)568 void IntervalHistogram::GetStddev(const FunctionCallbackInfo<Value>& args) {
569 IntervalHistogram* histogram;
570 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
571 args.GetReturnValue().Set((*histogram)->Stddev());
572 }
573
GetPercentile(const FunctionCallbackInfo<Value>& args)574 void IntervalHistogram::GetPercentile(const FunctionCallbackInfo<Value>& args) {
575 IntervalHistogram* histogram;
576 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
577 CHECK(args[0]->IsNumber());
578 double percentile = args[0].As<Number>()->Value();
579 double value = static_cast<double>((*histogram)->Percentile(percentile));
580 args.GetReturnValue().Set(value);
581 }
582
GetPercentileBigInt( const FunctionCallbackInfo<Value>& args)583 void IntervalHistogram::GetPercentileBigInt(
584 const FunctionCallbackInfo<Value>& args) {
585 Environment* env = Environment::GetCurrent(args);
586 IntervalHistogram* histogram;
587 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
588 CHECK(args[0]->IsNumber());
589 double percentile = args[0].As<Number>()->Value();
590 int64_t value = (*histogram)->Percentile(percentile);
591 args.GetReturnValue().Set(BigInt::New(env->isolate(), value));
592 }
593
GetPercentiles( const FunctionCallbackInfo<Value>& args)594 void IntervalHistogram::GetPercentiles(
595 const FunctionCallbackInfo<Value>& args) {
596 Environment* env = Environment::GetCurrent(args);
597 IntervalHistogram* histogram;
598 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
599 CHECK(args[0]->IsMap());
600 Local<Map> map = args[0].As<Map>();
601 (*histogram)->Percentiles([map, env](double key, int64_t value) {
602 USE(map->Set(
603 env->context(),
604 Number::New(env->isolate(), key),
605 Number::New(env->isolate(), static_cast<double>(value))));
606 });
607 }
608
GetPercentilesBigInt( const FunctionCallbackInfo<Value>& args)609 void IntervalHistogram::GetPercentilesBigInt(
610 const FunctionCallbackInfo<Value>& args) {
611 Environment* env = Environment::GetCurrent(args);
612 IntervalHistogram* histogram;
613 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
614 CHECK(args[0]->IsMap());
615 Local<Map> map = args[0].As<Map>();
616 (*histogram)->Percentiles([map, env](double key, int64_t value) {
617 USE(map->Set(
618 env->context(),
619 Number::New(env->isolate(), key),
620 BigInt::New(env->isolate(), value)));
621 });
622 }
623
DoReset(const FunctionCallbackInfo<Value>& args)624 void IntervalHistogram::DoReset(const FunctionCallbackInfo<Value>& args) {
625 IntervalHistogram* histogram;
626 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
627 (*histogram)->Reset();
628 }
629
630 std::unique_ptr<worker::TransferData>
CloneForMessaging() const631 IntervalHistogram::CloneForMessaging() const {
632 return std::make_unique<HistogramBase::HistogramTransferData>(histogram());
633 }
634
635 } // namespace node
636