GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: histogram.cc Lines: 292 363 80.4 %
Date: 2022-05-22 04:15:48 Branches: 68 162 42.0 %

Line Branch Exec Source
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::Local;
15
using v8::Map;
16
using v8::Number;
17
using v8::Object;
18
using v8::String;
19
using v8::Uint32;
20
using v8::Value;
21
22
11
Histogram::Histogram(const Options& options) {
23
  hdr_histogram* histogram;
24
11
  CHECK_EQ(0, hdr_init(options.lowest,
25
                       options.highest,
26
                       options.figures,
27
                       &histogram));
28
11
  histogram_.reset(histogram);
29
11
}
30
31
void Histogram::MemoryInfo(MemoryTracker* tracker) const {
32
  tracker->TrackFieldWithSize("histogram", GetMemorySize());
33
}
34
35
11
HistogramImpl::HistogramImpl(const Histogram::Options& options)
36
11
    : histogram_(new Histogram(options)) {}
37
38
2
HistogramImpl::HistogramImpl(std::shared_ptr<Histogram> histogram)
39
2
    : histogram_(std::move(histogram)) {}
40
41
8
HistogramBase::HistogramBase(
42
    Environment* env,
43
    Local<Object> wrap,
44
8
    const Histogram::Options& options)
45
    : BaseObject(env, wrap),
46
8
      HistogramImpl(options) {
47
8
  MakeWeak();
48
8
}
49
50
2
HistogramBase::HistogramBase(
51
    Environment* env,
52
    Local<Object> wrap,
53
2
    std::shared_ptr<Histogram> histogram)
54
    : BaseObject(env, wrap),
55
2
      HistogramImpl(std::move(histogram)) {
56
2
  MakeWeak();
57
2
}
58
59
void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
60
  tracker->TrackField("histogram", histogram());
61
}
62
63
7
void HistogramBase::GetCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
64
  HistogramBase* histogram;
65
7
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
66
7
  double value = static_cast<double>((*histogram)->Count());
67
14
  args.GetReturnValue().Set(value);
68
}
69
70
2
void HistogramBase::GetCountBigInt(
71
    const v8::FunctionCallbackInfo<v8::Value>& args) {
72
2
  Environment* env = Environment::GetCurrent(args);
73
  HistogramBase* histogram;
74
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
75
4
  args.GetReturnValue().Set(
76
      BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count()));
77
}
78
79
6
void HistogramBase::GetMin(const FunctionCallbackInfo<Value>& args) {
80
  HistogramBase* histogram;
81
6
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
82
6
  double value = static_cast<double>((*histogram)->Min());
83
12
  args.GetReturnValue().Set(value);
84
}
85
86
2
void HistogramBase::GetMinBigInt(const FunctionCallbackInfo<Value>& args) {
87
2
  Environment* env = Environment::GetCurrent(args);
88
  HistogramBase* histogram;
89
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
90
4
  args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
91
}
92
93
9
void HistogramBase::GetMax(const FunctionCallbackInfo<Value>& args) {
94
  HistogramBase* histogram;
95
9
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
96
9
  double value = static_cast<double>((*histogram)->Max());
97
18
  args.GetReturnValue().Set(value);
98
}
99
100
2
void HistogramBase::GetMaxBigInt(const FunctionCallbackInfo<Value>& args) {
101
2
  Environment* env = Environment::GetCurrent(args);
102
  HistogramBase* histogram;
103
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
104
4
  args.GetReturnValue().Set(
105
      BigInt::New(env->isolate(), (*histogram)->Max()));
106
}
107
108
4
void HistogramBase::GetMean(const FunctionCallbackInfo<Value>& args) {
109
  HistogramBase* histogram;
110
4
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
111
8
  args.GetReturnValue().Set((*histogram)->Mean());
112
}
113
114
4
void HistogramBase::GetExceeds(const FunctionCallbackInfo<Value>& args) {
115
  HistogramBase* histogram;
116
4
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
117
4
  double value = static_cast<double>((*histogram)->Exceeds());
118
8
  args.GetReturnValue().Set(value);
119
}
120
121
1
void HistogramBase::GetExceedsBigInt(const FunctionCallbackInfo<Value>& args) {
122
1
  Environment* env = Environment::GetCurrent(args);
123
  HistogramBase* histogram;
124
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
125
2
  args.GetReturnValue().Set(
126
      BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Exceeds()));
127
}
128
129
4
void HistogramBase::GetStddev(const FunctionCallbackInfo<Value>& args) {
130
  HistogramBase* histogram;
131
4
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
132
8
  args.GetReturnValue().Set((*histogram)->Stddev());
133
}
134
135
2
void HistogramBase::GetPercentile(const FunctionCallbackInfo<Value>& args) {
136
  HistogramBase* histogram;
137
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
138
2
  CHECK(args[0]->IsNumber());
139
4
  double percentile = args[0].As<Number>()->Value();
140
2
  double value = static_cast<double>((*histogram)->Percentile(percentile));
141
4
  args.GetReturnValue().Set(value);
142
}
143
144
2
void HistogramBase::GetPercentileBigInt(
145
    const FunctionCallbackInfo<Value>& args) {
146
2
  Environment* env = Environment::GetCurrent(args);
147
  HistogramBase* histogram;
148
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
149
2
  CHECK(args[0]->IsNumber());
150
4
  double percentile = args[0].As<Number>()->Value();
151
2
  int64_t value = (*histogram)->Percentile(percentile);
152
4
  args.GetReturnValue().Set(BigInt::New(env->isolate(), value));
153
}
154
155
1
void HistogramBase::GetPercentiles(const FunctionCallbackInfo<Value>& args) {
156
1
  Environment* env = Environment::GetCurrent(args);
157
  HistogramBase* histogram;
158
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
159
1
  CHECK(args[0]->IsMap());
160
1
  Local<Map> map = args[0].As<Map>();
161
1
  (*histogram)->Percentiles([map, env](double key, int64_t value) {
162
1
    USE(map->Set(
163
          env->context(),
164
          Number::New(env->isolate(), key),
165
3
          Number::New(env->isolate(), static_cast<double>(value))));
166
1
  });
167
}
168
169
void HistogramBase::GetPercentilesBigInt(
170
    const FunctionCallbackInfo<Value>& args) {
171
  Environment* env = Environment::GetCurrent(args);
172
  HistogramBase* histogram;
173
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
174
  CHECK(args[0]->IsMap());
175
  Local<Map> map = args[0].As<Map>();
176
  (*histogram)->Percentiles([map, env](double key, int64_t value) {
177
    USE(map->Set(
178
          env->context(),
179
          Number::New(env->isolate(), key),
180
          BigInt::New(env->isolate(), value)));
181
  });
182
}
183
184
void HistogramBase::DoReset(const FunctionCallbackInfo<Value>& args) {
185
  HistogramBase* histogram;
186
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
187
  (*histogram)->Reset();
188
}
189
190
1
void HistogramBase::RecordDelta(const FunctionCallbackInfo<Value>& args) {
191
  HistogramBase* histogram;
192
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
193
1
  (*histogram)->RecordDelta();
194
}
195
196
23
void HistogramBase::Record(const FunctionCallbackInfo<Value>& args) {
197
23
  Environment* env = Environment::GetCurrent(args);
198

24
  CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
199
23
  bool lossless = true;
200
23
  int64_t value = args[0]->IsBigInt()
201
47
      ? args[0].As<BigInt>()->Int64Value(&lossless)
202
44
      : static_cast<int64_t>(args[0].As<Number>()->Value());
203

23
  if (!lossless || value < 1)
204
    return THROW_ERR_OUT_OF_RANGE(env, "value is out of range");
205
  HistogramBase* histogram;
206
23
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
207
23
  (*histogram)->Record(value);
208
}
209
210
1
void HistogramBase::Add(const FunctionCallbackInfo<Value>& args) {
211
1
  Environment* env = Environment::GetCurrent(args);
212
  HistogramBase* histogram;
213
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
214
215

3
  CHECK(GetConstructorTemplate(env)->HasInstance(args[0]));
216
  HistogramBase* other;
217
1
  ASSIGN_OR_RETURN_UNWRAP(&other, args[0]);
218
219
1
  double count = (*histogram)->Add(*(other->histogram()));
220
2
  args.GetReturnValue().Set(count);
221
}
222
223
BaseObjectPtr<HistogramBase> HistogramBase::Create(
224
    Environment* env,
225
    const Histogram::Options& options) {
226
  Local<Object> obj;
227
  if (!GetConstructorTemplate(env)
228
          ->InstanceTemplate()
229
          ->NewInstance(env->context()).ToLocal(&obj)) {
230
    return BaseObjectPtr<HistogramBase>();
231
  }
232
233
  return MakeBaseObject<HistogramBase>(env, obj, options);
234
}
235
236
2
BaseObjectPtr<HistogramBase> HistogramBase::Create(
237
    Environment* env,
238
    std::shared_ptr<Histogram> histogram) {
239
  Local<Object> obj;
240
2
  if (!GetConstructorTemplate(env)
241
2
          ->InstanceTemplate()
242
4
          ->NewInstance(env->context()).ToLocal(&obj)) {
243
    return BaseObjectPtr<HistogramBase>();
244
  }
245
2
  return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
246
}
247
248
8
void HistogramBase::New(const FunctionCallbackInfo<Value>& args) {
249
8
  CHECK(args.IsConstructCall());
250
8
  Environment* env = Environment::GetCurrent(args);
251
252

8
  CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
253

8
  CHECK_IMPLIES(!args[1]->IsNumber(), args[1]->IsBigInt());
254
8
  CHECK(args[2]->IsUint32());
255
256
8
  int64_t lowest = 1;
257
8
  int64_t highest = std::numeric_limits<int64_t>::max();
258
259
  bool lossless_ignored;
260
261
8
  if (args[0]->IsNumber()) {
262
16
    lowest = args[0].As<Integer>()->Value();
263
  } else if (args[0]->IsBigInt()) {
264
    lowest = args[0].As<BigInt>()->Int64Value(&lossless_ignored);
265
  }
266
267
8
  if (args[1]->IsNumber()) {
268
16
    highest = args[1].As<Integer>()->Value();
269
  } else if (args[1]->IsBigInt()) {
270
    highest = args[1].As<BigInt>()->Int64Value(&lossless_ignored);
271
  }
272
273
16
  int32_t figures = args[2].As<Uint32>()->Value();
274
16
  new HistogramBase(env, args.This(), Histogram::Options {
275
    lowest, highest, figures
276
8
  });
277
8
}
278
279
851
Local<FunctionTemplate> HistogramBase::GetConstructorTemplate(
280
    Environment* env) {
281
851
  Local<FunctionTemplate> tmpl = env->histogram_ctor_template();
282
851
  if (tmpl.IsEmpty()) {
283
848
    tmpl = env->NewFunctionTemplate(New);
284
    Local<String> classname =
285
848
        FIXED_ONE_BYTE_STRING(env->isolate(), "Histogram");
286
848
    tmpl->SetClassName(classname);
287
848
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
288
289
1696
    tmpl->InstanceTemplate()->SetInternalFieldCount(
290
        HistogramBase::kInternalFieldCount);
291
848
    env->SetProtoMethodNoSideEffect(tmpl, "count", GetCount);
292
848
    env->SetProtoMethodNoSideEffect(tmpl, "countBigInt", GetCountBigInt);
293
848
    env->SetProtoMethodNoSideEffect(tmpl, "exceeds", GetExceeds);
294
848
    env->SetProtoMethodNoSideEffect(tmpl, "exceedsBigInt", GetExceedsBigInt);
295
848
    env->SetProtoMethodNoSideEffect(tmpl, "min", GetMin);
296
848
    env->SetProtoMethodNoSideEffect(tmpl, "minBigInt", GetMinBigInt);
297
848
    env->SetProtoMethodNoSideEffect(tmpl, "max", GetMax);
298
848
    env->SetProtoMethodNoSideEffect(tmpl, "maxBigInt", GetMaxBigInt);
299
848
    env->SetProtoMethodNoSideEffect(tmpl, "mean", GetMean);
300
848
    env->SetProtoMethodNoSideEffect(tmpl, "stddev", GetStddev);
301
848
    env->SetProtoMethodNoSideEffect(tmpl, "percentile", GetPercentile);
302
848
    env->SetProtoMethodNoSideEffect(tmpl, "percentileBigInt",
303
                                    GetPercentileBigInt);
304
848
    env->SetProtoMethodNoSideEffect(tmpl, "percentiles", GetPercentiles);
305
848
    env->SetProtoMethodNoSideEffect(tmpl, "percentilesBigInt",
306
                                    GetPercentilesBigInt);
307
848
    env->SetProtoMethod(tmpl, "reset", DoReset);
308
848
    env->SetProtoMethod(tmpl, "record", Record);
309
848
    env->SetProtoMethod(tmpl, "recordDelta", RecordDelta);
310
848
    env->SetProtoMethod(tmpl, "add", Add);
311
848
    env->set_histogram_ctor_template(tmpl);
312
  }
313
851
  return tmpl;
314
}
315
316
5184
void HistogramBase::RegisterExternalReferences(
317
    ExternalReferenceRegistry* registry) {
318
5184
  registry->Register(New);
319
5184
  registry->Register(GetCount);
320
5184
  registry->Register(GetCountBigInt);
321
5184
  registry->Register(GetExceeds);
322
5184
  registry->Register(GetExceedsBigInt);
323
5184
  registry->Register(GetMin);
324
5184
  registry->Register(GetMinBigInt);
325
5184
  registry->Register(GetMax);
326
5184
  registry->Register(GetMaxBigInt);
327
5184
  registry->Register(GetMean);
328
5184
  registry->Register(GetStddev);
329
5184
  registry->Register(GetPercentile);
330
5184
  registry->Register(GetPercentileBigInt);
331
5184
  registry->Register(GetPercentiles);
332
5184
  registry->Register(GetPercentilesBigInt);
333
5184
  registry->Register(DoReset);
334
5184
  registry->Register(Record);
335
5184
  registry->Register(RecordDelta);
336
5184
  registry->Register(Add);
337
5184
}
338
339
848
void HistogramBase::Initialize(Environment* env, Local<Object> target) {
340
848
  env->SetConstructorFunction(target, "Histogram", GetConstructorTemplate(env));
341
848
}
342
343
2
BaseObjectPtr<BaseObject> HistogramBase::HistogramTransferData::Deserialize(
344
    Environment* env,
345
    v8::Local<v8::Context> context,
346
    std::unique_ptr<worker::TransferData> self) {
347
2
  return Create(env, std::move(histogram_));
348
}
349
350
1
std::unique_ptr<worker::TransferData> HistogramBase::CloneForMessaging() const {
351
1
  return std::make_unique<HistogramTransferData>(this);
352
}
353
354
void HistogramBase::HistogramTransferData::MemoryInfo(
355
    MemoryTracker* tracker) const {
356
  tracker->TrackField("histogram", histogram_);
357
}
358
359
3
Local<FunctionTemplate> IntervalHistogram::GetConstructorTemplate(
360
    Environment* env) {
361
3
  Local<FunctionTemplate> tmpl = env->intervalhistogram_constructor_template();
362
3
  if (tmpl.IsEmpty()) {
363
2
    tmpl = FunctionTemplate::New(env->isolate());
364
2
    tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
365
4
    tmpl->InstanceTemplate()->SetInternalFieldCount(
366
        HistogramBase::kInternalFieldCount);
367
2
    env->SetProtoMethodNoSideEffect(tmpl, "count", GetCount);
368
2
    env->SetProtoMethodNoSideEffect(tmpl, "countBigInt", GetCountBigInt);
369
2
    env->SetProtoMethodNoSideEffect(tmpl, "exceeds", GetExceeds);
370
2
    env->SetProtoMethodNoSideEffect(tmpl, "exceedsBigInt", GetExceedsBigInt);
371
2
    env->SetProtoMethodNoSideEffect(tmpl, "min", GetMin);
372
2
    env->SetProtoMethodNoSideEffect(tmpl, "minBigInt", GetMinBigInt);
373
2
    env->SetProtoMethodNoSideEffect(tmpl, "max", GetMax);
374
2
    env->SetProtoMethodNoSideEffect(tmpl, "maxBigInt", GetMaxBigInt);
375
2
    env->SetProtoMethodNoSideEffect(tmpl, "mean", GetMean);
376
2
    env->SetProtoMethodNoSideEffect(tmpl, "stddev", GetStddev);
377
2
    env->SetProtoMethodNoSideEffect(tmpl, "percentile", GetPercentile);
378
2
    env->SetProtoMethodNoSideEffect(tmpl, "percentileBigInt",
379
                                    GetPercentileBigInt);
380
2
    env->SetProtoMethodNoSideEffect(tmpl, "percentiles", GetPercentiles);
381
2
    env->SetProtoMethodNoSideEffect(tmpl, "percentilesBigInt",
382
                                    GetPercentilesBigInt);
383
2
    env->SetProtoMethod(tmpl, "reset", DoReset);
384
2
    env->SetProtoMethod(tmpl, "start", Start);
385
2
    env->SetProtoMethod(tmpl, "stop", Stop);
386
2
    env->set_intervalhistogram_constructor_template(tmpl);
387
  }
388
3
  return tmpl;
389
}
390
391
5184
void IntervalHistogram::RegisterExternalReferences(
392
    ExternalReferenceRegistry* registry) {
393
5184
  registry->Register(GetCount);
394
5184
  registry->Register(GetCountBigInt);
395
5184
  registry->Register(GetExceeds);
396
5184
  registry->Register(GetExceedsBigInt);
397
5184
  registry->Register(GetMin);
398
5184
  registry->Register(GetMinBigInt);
399
5184
  registry->Register(GetMax);
400
5184
  registry->Register(GetMaxBigInt);
401
5184
  registry->Register(GetMean);
402
5184
  registry->Register(GetStddev);
403
5184
  registry->Register(GetPercentile);
404
5184
  registry->Register(GetPercentileBigInt);
405
5184
  registry->Register(GetPercentiles);
406
5184
  registry->Register(GetPercentilesBigInt);
407
5184
  registry->Register(DoReset);
408
5184
  registry->Register(Start);
409
5184
  registry->Register(Stop);
410
5184
}
411
412
3
IntervalHistogram::IntervalHistogram(
413
    Environment* env,
414
    Local<Object> wrap,
415
    AsyncWrap::ProviderType type,
416
    int32_t interval,
417
    std::function<void(Histogram&)> on_interval,
418
3
    const Histogram::Options& options)
419
    : HandleWrap(
420
          env,
421
          wrap,
422
3
          reinterpret_cast<uv_handle_t*>(&timer_),
423
          type),
424
      HistogramImpl(options),
425
      interval_(interval),
426
3
      on_interval_(std::move(on_interval)) {
427
3
  MakeWeak();
428
3
  uv_timer_init(env->event_loop(), &timer_);
429
3
}
430
431
3
BaseObjectPtr<IntervalHistogram> IntervalHistogram::Create(
432
    Environment* env,
433
    int32_t interval,
434
    std::function<void(Histogram&)> on_interval,
435
    const Histogram::Options& options) {
436
  Local<Object> obj;
437
3
  if (!GetConstructorTemplate(env)
438
3
          ->InstanceTemplate()
439
6
          ->NewInstance(env->context()).ToLocal(&obj)) {
440
    return BaseObjectPtr<IntervalHistogram>();
441
  }
442
443
  return MakeBaseObject<IntervalHistogram>(
444
      env,
445
      obj,
446
3
      AsyncWrap::PROVIDER_ELDHISTOGRAM,
447
      interval,
448
3
      std::move(on_interval),
449
3
      options);
450
}
451
452
1760
void IntervalHistogram::TimerCB(uv_timer_t* handle) {
453
  IntervalHistogram* histogram =
454
1760
      ContainerOf(&IntervalHistogram::timer_, handle);
455
456
1760
  Histogram* h = histogram->histogram().get();
457
458
1760
  histogram->on_interval_(*h);
459
1760
}
460
461
void IntervalHistogram::MemoryInfo(MemoryTracker* tracker) const {
462
  tracker->TrackField("histogram", histogram());
463
}
464
465
3
void IntervalHistogram::OnStart(StartFlags flags) {
466

3
  if (enabled_ || IsHandleClosing()) return;
467
3
  enabled_ = true;
468
3
  if (flags == StartFlags::RESET)
469
    histogram()->Reset();
470
3
  uv_timer_start(&timer_, TimerCB, interval_, interval_);
471
3
  uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
472
}
473
474
2
void IntervalHistogram::OnStop() {
475

2
  if (!enabled_ || IsHandleClosing()) return;
476
2
  enabled_ = false;
477
2
  uv_timer_stop(&timer_);
478
}
479
480
3
void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
481
  IntervalHistogram* histogram;
482
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
483

6
  histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE);
484
}
485
486
2
void IntervalHistogram::Stop(const FunctionCallbackInfo<Value>& args) {
487
  IntervalHistogram* histogram;
488
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
489
2
  histogram->OnStop();
490
}
491
492
1
void IntervalHistogram::GetCount(const FunctionCallbackInfo<Value>& args) {
493
  IntervalHistogram* histogram;
494
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
495
1
  double value = static_cast<double>((*histogram)->Count());
496
2
  args.GetReturnValue().Set(value);
497
}
498
499
void IntervalHistogram::GetCountBigInt(
500
    const v8::FunctionCallbackInfo<v8::Value>& args) {
501
  Environment* env = Environment::GetCurrent(args);
502
  IntervalHistogram* histogram;
503
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
504
  args.GetReturnValue().Set(
505
      BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count()));
506
}
507
508
2
void IntervalHistogram::GetMin(const FunctionCallbackInfo<Value>& args) {
509
  IntervalHistogram* histogram;
510
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
511
2
  double value = static_cast<double>((*histogram)->Min());
512
4
  args.GetReturnValue().Set(value);
513
}
514
515
void IntervalHistogram::GetMinBigInt(const FunctionCallbackInfo<Value>& args) {
516
  Environment* env = Environment::GetCurrent(args);
517
  IntervalHistogram* histogram;
518
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
519
  args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
520
}
521
522
2
void IntervalHistogram::GetMax(const FunctionCallbackInfo<Value>& args) {
523
  IntervalHistogram* histogram;
524
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
525
2
  double value = static_cast<double>((*histogram)->Max());
526
4
  args.GetReturnValue().Set(value);
527
}
528
529
void IntervalHistogram::GetMaxBigInt(const FunctionCallbackInfo<Value>& args) {
530
  Environment* env = Environment::GetCurrent(args);
531
  IntervalHistogram* histogram;
532
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
533
  args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
534
}
535
536
2
void IntervalHistogram::GetMean(const FunctionCallbackInfo<Value>& args) {
537
  IntervalHistogram* histogram;
538
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
539
4
  args.GetReturnValue().Set((*histogram)->Mean());
540
}
541
542
void IntervalHistogram::GetExceeds(const FunctionCallbackInfo<Value>& args) {
543
  IntervalHistogram* histogram;
544
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
545
  double value = static_cast<double>((*histogram)->Exceeds());
546
  args.GetReturnValue().Set(value);
547
}
548
549
void IntervalHistogram::GetExceedsBigInt(
550
    const FunctionCallbackInfo<Value>& args) {
551
  Environment* env = Environment::GetCurrent(args);
552
  IntervalHistogram* histogram;
553
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
554
  args.GetReturnValue().Set(
555
      BigInt::New(env->isolate(), (*histogram)->Exceeds()));
556
}
557
558
2
void IntervalHistogram::GetStddev(const FunctionCallbackInfo<Value>& args) {
559
  IntervalHistogram* histogram;
560
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
561
4
  args.GetReturnValue().Set((*histogram)->Stddev());
562
}
563
564
991
void IntervalHistogram::GetPercentile(const FunctionCallbackInfo<Value>& args) {
565
  IntervalHistogram* histogram;
566
991
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
567
991
  CHECK(args[0]->IsNumber());
568
1982
  double percentile = args[0].As<Number>()->Value();
569
991
  double value = static_cast<double>((*histogram)->Percentile(percentile));
570
1982
  args.GetReturnValue().Set(value);
571
}
572
573
void IntervalHistogram::GetPercentileBigInt(
574
    const FunctionCallbackInfo<Value>& args) {
575
  Environment* env = Environment::GetCurrent(args);
576
  IntervalHistogram* histogram;
577
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
578
  CHECK(args[0]->IsNumber());
579
  double percentile = args[0].As<Number>()->Value();
580
  int64_t value = (*histogram)->Percentile(percentile);
581
  args.GetReturnValue().Set(BigInt::New(env->isolate(), value));
582
}
583
584
2
void IntervalHistogram::GetPercentiles(
585
    const FunctionCallbackInfo<Value>& args) {
586
2
  Environment* env = Environment::GetCurrent(args);
587
  IntervalHistogram* histogram;
588
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
589
2
  CHECK(args[0]->IsMap());
590
2
  Local<Map> map = args[0].As<Map>();
591
2
  (*histogram)->Percentiles([map, env](double key, int64_t value) {
592
14
    USE(map->Set(
593
          env->context(),
594
          Number::New(env->isolate(), key),
595
42
          Number::New(env->isolate(), static_cast<double>(value))));
596
14
  });
597
}
598
599
void IntervalHistogram::GetPercentilesBigInt(
600
    const FunctionCallbackInfo<Value>& args) {
601
  Environment* env = Environment::GetCurrent(args);
602
  IntervalHistogram* histogram;
603
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
604
  CHECK(args[0]->IsMap());
605
  Local<Map> map = args[0].As<Map>();
606
  (*histogram)->Percentiles([map, env](double key, int64_t value) {
607
    USE(map->Set(
608
          env->context(),
609
          Number::New(env->isolate(), key),
610
          BigInt::New(env->isolate(), value)));
611
  });
612
}
613
614
2
void IntervalHistogram::DoReset(const FunctionCallbackInfo<Value>& args) {
615
  IntervalHistogram* histogram;
616
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
617
2
  (*histogram)->Reset();
618
}
619
620
std::unique_ptr<worker::TransferData>
621
1
IntervalHistogram::CloneForMessaging() const {
622
1
  return std::make_unique<HistogramBase::HistogramTransferData>(histogram());
623
}
624
625
}  // namespace node