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

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

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

3
  CHECK(GetConstructorTemplate(env)->HasInstance(args[0]));
217
  HistogramBase* other;
218
1
  ASSIGN_OR_RETURN_UNWRAP(&other, args[0]);
219
220
1
  double count = (*histogram)->Add(*(other->histogram()));
221
2
  args.GetReturnValue().Set(count);
222
}
223
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
237
2
BaseObjectPtr<HistogramBase> HistogramBase::Create(
238
    Environment* env,
239
    std::shared_ptr<Histogram> histogram) {
240
  Local<Object> obj;
241
2
  if (!GetConstructorTemplate(env)
242
2
          ->InstanceTemplate()
243
4
          ->NewInstance(env->context()).ToLocal(&obj)) {
244
    return BaseObjectPtr<HistogramBase>();
245
  }
246
2
  return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
247
}
248
249
8
void HistogramBase::New(const FunctionCallbackInfo<Value>& args) {
250
8
  CHECK(args.IsConstructCall());
251
8
  Environment* env = Environment::GetCurrent(args);
252
253

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

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

3
  if (enabled_ || IsHandleClosing()) return;
473
3
  enabled_ = true;
474
3
  if (flags == StartFlags::RESET)
475
    histogram()->Reset();
476
3
  uv_timer_start(&timer_, TimerCB, interval_, interval_);
477
3
  uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
478
}
479
480
2
void IntervalHistogram::OnStop() {
481

2
  if (!enabled_ || IsHandleClosing()) return;
482
2
  enabled_ = false;
483
2
  uv_timer_stop(&timer_);
484
}
485
486
3
void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
487
  IntervalHistogram* histogram;
488
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
489

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