GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/histogram.cc Lines: 172 205 83.9 %
Date: 2021-04-24 04:15:50 Branches: 44 92 47.8 %

Line Branch Exec Source
1
#include "histogram.h"  // NOLINT(build/include_inline)
2
#include "histogram-inl.h"
3
#include "base_object-inl.h"
4
#include "memory_tracker-inl.h"
5
#include "node_errors.h"
6
namespace node {
7
8
using v8::BigInt;
9
using v8::FunctionCallbackInfo;
10
using v8::FunctionTemplate;
11
using v8::Local;
12
using v8::Map;
13
using v8::Number;
14
using v8::Object;
15
using v8::String;
16
using v8::Value;
17
18
6
Histogram::Histogram(int64_t lowest, int64_t highest, int figures) {
19
  hdr_histogram* histogram;
20
6
  CHECK_EQ(0, hdr_init(lowest, highest, figures, &histogram));
21
6
  histogram_.reset(histogram);
22
6
}
23
24
void Histogram::MemoryInfo(MemoryTracker* tracker) const {
25
  tracker->TrackFieldWithSize("histogram", GetMemorySize());
26
}
27
28
6
HistogramImpl::HistogramImpl(int64_t lowest, int64_t highest, int figures)
29
6
    : histogram_(new Histogram(lowest, highest, figures)) {}
30
31
2
HistogramImpl::HistogramImpl(std::shared_ptr<Histogram> histogram)
32
2
    : histogram_(std::move(histogram)) {}
33
34
3
HistogramBase::HistogramBase(
35
    Environment* env,
36
    Local<Object> wrap,
37
    int64_t lowest,
38
    int64_t highest,
39
3
    int figures)
40
    : BaseObject(env, wrap),
41
3
      HistogramImpl(lowest, highest, figures) {
42
3
  MakeWeak();
43
3
}
44
45
2
HistogramBase::HistogramBase(
46
    Environment* env,
47
    Local<Object> wrap,
48
2
    std::shared_ptr<Histogram> histogram)
49
    : BaseObject(env, wrap),
50
2
      HistogramImpl(std::move(histogram)) {
51
2
  MakeWeak();
52
2
}
53
54
void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
55
  tracker->TrackField("histogram", histogram());
56
}
57
58
5
void HistogramBase::GetMin(const FunctionCallbackInfo<Value>& args) {
59
  HistogramBase* histogram;
60
5
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
61
5
  double value = static_cast<double>((*histogram)->Min());
62
10
  args.GetReturnValue().Set(value);
63
}
64
65
8
void HistogramBase::GetMax(const FunctionCallbackInfo<Value>& args) {
66
  HistogramBase* histogram;
67
8
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
68
8
  double value = static_cast<double>((*histogram)->Max());
69
16
  args.GetReturnValue().Set(value);
70
}
71
72
3
void HistogramBase::GetMean(const FunctionCallbackInfo<Value>& args) {
73
  HistogramBase* histogram;
74
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
75
9
  args.GetReturnValue().Set((*histogram)->Mean());
76
}
77
78
3
void HistogramBase::GetExceeds(const FunctionCallbackInfo<Value>& args) {
79
  HistogramBase* histogram;
80
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
81
3
  double value = static_cast<double>((*histogram)->Exceeds());
82
6
  args.GetReturnValue().Set(value);
83
}
84
85
3
void HistogramBase::GetStddev(const FunctionCallbackInfo<Value>& args) {
86
  HistogramBase* histogram;
87
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
88
9
  args.GetReturnValue().Set((*histogram)->Stddev());
89
}
90
91
2
void HistogramBase::GetPercentile(const FunctionCallbackInfo<Value>& args) {
92
  HistogramBase* histogram;
93
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
94
4
  CHECK(args[0]->IsNumber());
95
6
  double percentile = args[0].As<Number>()->Value();
96
6
  args.GetReturnValue().Set((*histogram)->Percentile(percentile));
97
}
98
99
void HistogramBase::GetPercentiles(const FunctionCallbackInfo<Value>& args) {
100
  Environment* env = Environment::GetCurrent(args);
101
  HistogramBase* histogram;
102
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
103
  CHECK(args[0]->IsMap());
104
  Local<Map> map = args[0].As<Map>();
105
  (*histogram)->Percentiles([map, env](double key, double value) {
106
    map->Set(
107
        env->context(),
108
        Number::New(env->isolate(), key),
109
        Number::New(env->isolate(), value)).IsEmpty();
110
  });
111
}
112
113
void HistogramBase::DoReset(const FunctionCallbackInfo<Value>& args) {
114
  HistogramBase* histogram;
115
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
116
  (*histogram)->Reset();
117
}
118
119
1
void HistogramBase::RecordDelta(const FunctionCallbackInfo<Value>& args) {
120
  HistogramBase* histogram;
121
1
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
122
1
  (*histogram)->RecordDelta();
123
}
124
125
22
void HistogramBase::Record(const FunctionCallbackInfo<Value>& args) {
126
22
  Environment* env = Environment::GetCurrent(args);
127

46
  CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
128
22
  bool lossless = true;
129
66
  int64_t value = args[0]->IsBigInt()
130
68
      ? args[0].As<BigInt>()->Int64Value(&lossless)
131
85
      : static_cast<int64_t>(args[0].As<Number>()->Value());
132

22
  if (!lossless || value < 1)
133
    return THROW_ERR_OUT_OF_RANGE(env, "value is out of range");
134
  HistogramBase* histogram;
135
22
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
136
22
  (*histogram)->Record(value);
137
}
138
139
BaseObjectPtr<HistogramBase> HistogramBase::Create(
140
    Environment* env,
141
    int64_t lowest,
142
    int64_t highest,
143
    int figures) {
144
  Local<Object> obj;
145
  if (!GetConstructorTemplate(env)
146
          ->InstanceTemplate()
147
          ->NewInstance(env->context()).ToLocal(&obj)) {
148
    return BaseObjectPtr<HistogramBase>();
149
  }
150
151
  return MakeBaseObject<HistogramBase>(
152
      env, obj, lowest, highest, figures);
153
}
154
155
2
BaseObjectPtr<HistogramBase> HistogramBase::Create(
156
    Environment* env,
157
    std::shared_ptr<Histogram> histogram) {
158
  Local<Object> obj;
159
6
  if (!GetConstructorTemplate(env)
160
4
          ->InstanceTemplate()
161
8
          ->NewInstance(env->context()).ToLocal(&obj)) {
162
    return BaseObjectPtr<HistogramBase>();
163
  }
164
2
  return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
165
}
166
167
3
void HistogramBase::New(const FunctionCallbackInfo<Value>& args) {
168
3
  CHECK(args.IsConstructCall());
169
3
  Environment* env = Environment::GetCurrent(args);
170
6
  new HistogramBase(env, args.This());
171
3
}
172
173
4396
Local<FunctionTemplate> HistogramBase::GetConstructorTemplate(
174
    Environment* env) {
175
4396
  Local<FunctionTemplate> tmpl = env->histogram_ctor_template();
176
4396
  if (tmpl.IsEmpty()) {
177
4394
    tmpl = env->NewFunctionTemplate(New);
178
    Local<String> classname =
179
4394
        FIXED_ONE_BYTE_STRING(env->isolate(), "Histogram");
180
4394
    tmpl->SetClassName(classname);
181
8788
    tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
182
183
13182
    tmpl->InstanceTemplate()->SetInternalFieldCount(
184
4394
        HistogramBase::kInternalFieldCount);
185
4394
    env->SetProtoMethodNoSideEffect(tmpl, "exceeds", GetExceeds);
186
4394
    env->SetProtoMethodNoSideEffect(tmpl, "min", GetMin);
187
4394
    env->SetProtoMethodNoSideEffect(tmpl, "max", GetMax);
188
4394
    env->SetProtoMethodNoSideEffect(tmpl, "mean", GetMean);
189
4394
    env->SetProtoMethodNoSideEffect(tmpl, "stddev", GetStddev);
190
4394
    env->SetProtoMethodNoSideEffect(tmpl, "percentile", GetPercentile);
191
4394
    env->SetProtoMethodNoSideEffect(tmpl, "percentiles", GetPercentiles);
192
4394
    env->SetProtoMethod(tmpl, "reset", DoReset);
193
4394
    env->SetProtoMethod(tmpl, "record", Record);
194
4394
    env->SetProtoMethod(tmpl, "recordDelta", RecordDelta);
195
4394
    env->set_histogram_ctor_template(tmpl);
196
  }
197
4396
  return tmpl;
198
}
199
200
4394
void HistogramBase::Initialize(Environment* env, Local<Object> target) {
201
4394
  env->SetConstructorFunction(target, "Histogram", GetConstructorTemplate(env));
202
4394
}
203
204
2
BaseObjectPtr<BaseObject> HistogramBase::HistogramTransferData::Deserialize(
205
    Environment* env,
206
    v8::Local<v8::Context> context,
207
    std::unique_ptr<worker::TransferData> self) {
208
2
  return Create(env, std::move(histogram_));
209
}
210
211
1
std::unique_ptr<worker::TransferData> HistogramBase::CloneForMessaging() const {
212
1
  return std::make_unique<HistogramTransferData>(this);
213
}
214
215
void HistogramBase::HistogramTransferData::MemoryInfo(
216
    MemoryTracker* tracker) const {
217
  tracker->TrackField("histogram", histogram_);
218
}
219
220
4394
Local<FunctionTemplate> IntervalHistogram::GetConstructorTemplate(
221
    Environment* env) {
222
4394
  Local<FunctionTemplate> tmpl = env->intervalhistogram_constructor_template();
223
4394
  if (tmpl.IsEmpty()) {
224
4394
    tmpl = FunctionTemplate::New(env->isolate());
225
8788
    tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
226
13182
    tmpl->InstanceTemplate()->SetInternalFieldCount(
227
4394
        HistogramBase::kInternalFieldCount);
228
4394
    env->SetProtoMethodNoSideEffect(tmpl, "exceeds", GetExceeds);
229
4394
    env->SetProtoMethodNoSideEffect(tmpl, "min", GetMin);
230
4394
    env->SetProtoMethodNoSideEffect(tmpl, "max", GetMax);
231
4394
    env->SetProtoMethodNoSideEffect(tmpl, "mean", GetMean);
232
4394
    env->SetProtoMethodNoSideEffect(tmpl, "stddev", GetStddev);
233
4394
    env->SetProtoMethodNoSideEffect(tmpl, "percentile", GetPercentile);
234
4394
    env->SetProtoMethodNoSideEffect(tmpl, "percentiles", GetPercentiles);
235
4394
    env->SetProtoMethod(tmpl, "reset", DoReset);
236
4394
    env->SetProtoMethod(tmpl, "start", Start);
237
4394
    env->SetProtoMethod(tmpl, "stop", Stop);
238
4394
    env->set_intervalhistogram_constructor_template(tmpl);
239
  }
240
4394
  return tmpl;
241
}
242
243
3
IntervalHistogram::IntervalHistogram(
244
    Environment* env,
245
    Local<Object> wrap,
246
    AsyncWrap::ProviderType type,
247
    int32_t interval,
248
    int64_t lowest,
249
    int64_t highest,
250
3
    int figures)
251
    : HandleWrap(
252
          env,
253
          wrap,
254
3
          reinterpret_cast<uv_handle_t*>(&timer_),
255
          type),
256
      HistogramImpl(lowest, highest, figures),
257
3
      interval_(interval) {
258
3
  MakeWeak();
259
3
  uv_timer_init(env->event_loop(), &timer_);
260
3
}
261
262
1767
void IntervalHistogram::TimerCB(uv_timer_t* handle) {
263
  IntervalHistogram* histogram =
264
1767
      ContainerOf(&IntervalHistogram::timer_, handle);
265
1767
  histogram->OnInterval();
266
1767
}
267
268
void IntervalHistogram::MemoryInfo(MemoryTracker* tracker) const {
269
  tracker->TrackField("histogram", histogram());
270
}
271
272
3
void IntervalHistogram::OnStart(StartFlags flags) {
273

3
  if (enabled_ || IsHandleClosing()) return;
274
3
  enabled_ = true;
275
3
  if (flags == StartFlags::RESET)
276
    histogram()->Reset();
277
3
  uv_timer_start(&timer_, TimerCB, interval_, interval_);
278
3
  uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
279
}
280
281
2
void IntervalHistogram::OnStop() {
282

2
  if (!enabled_ || IsHandleClosing()) return;
283
2
  enabled_ = false;
284
2
  uv_timer_stop(&timer_);
285
}
286
287
3
void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
288
  IntervalHistogram* histogram;
289
3
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
290
6
  histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE);
291
}
292
293
2
void IntervalHistogram::Stop(const FunctionCallbackInfo<Value>& args) {
294
  IntervalHistogram* histogram;
295
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
296
2
  histogram->OnStop();
297
}
298
299
2
void IntervalHistogram::GetMin(const FunctionCallbackInfo<Value>& args) {
300
  IntervalHistogram* histogram;
301
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
302
2
  double value = static_cast<double>((*histogram)->Min());
303
4
  args.GetReturnValue().Set(value);
304
}
305
306
2
void IntervalHistogram::GetMax(const FunctionCallbackInfo<Value>& args) {
307
  IntervalHistogram* histogram;
308
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
309
2
  double value = static_cast<double>((*histogram)->Max());
310
4
  args.GetReturnValue().Set(value);
311
}
312
313
2
void IntervalHistogram::GetMean(const FunctionCallbackInfo<Value>& args) {
314
  IntervalHistogram* histogram;
315
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
316
6
  args.GetReturnValue().Set((*histogram)->Mean());
317
}
318
319
void IntervalHistogram::GetExceeds(const FunctionCallbackInfo<Value>& args) {
320
  IntervalHistogram* histogram;
321
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
322
  double value = static_cast<double>((*histogram)->Exceeds());
323
  args.GetReturnValue().Set(value);
324
}
325
326
2
void IntervalHistogram::GetStddev(const FunctionCallbackInfo<Value>& args) {
327
  IntervalHistogram* histogram;
328
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
329
6
  args.GetReturnValue().Set((*histogram)->Stddev());
330
}
331
332
991
void IntervalHistogram::GetPercentile(const FunctionCallbackInfo<Value>& args) {
333
  IntervalHistogram* histogram;
334
991
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
335
1982
  CHECK(args[0]->IsNumber());
336
2973
  double percentile = args[0].As<Number>()->Value();
337
2973
  args.GetReturnValue().Set((*histogram)->Percentile(percentile));
338
}
339
340
2
void IntervalHistogram::GetPercentiles(
341
    const FunctionCallbackInfo<Value>& args) {
342
2
  Environment* env = Environment::GetCurrent(args);
343
  IntervalHistogram* histogram;
344
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
345
4
  CHECK(args[0]->IsMap());
346
4
  Local<Map> map = args[0].As<Map>();
347
46
  (*histogram)->Percentiles([map, env](double key, double value) {
348
28
    map->Set(
349
        env->context(),
350
        Number::New(env->isolate(), key),
351
70
        Number::New(env->isolate(), value)).IsEmpty();
352
16
  });
353
}
354
355
2
void IntervalHistogram::DoReset(const FunctionCallbackInfo<Value>& args) {
356
  IntervalHistogram* histogram;
357
2
  ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
358
2
  (*histogram)->Reset();
359
}
360
361
std::unique_ptr<worker::TransferData>
362
1
IntervalHistogram::CloneForMessaging() const {
363
1
  return std::make_unique<HistogramBase::HistogramTransferData>(histogram());
364
}
365
366

14316
}  // namespace node