1 #include "histogram.h" // NOLINT(build/include_inline)
2 #include "histogram-inl.h"
3 #include "memory_tracker-inl.h"
4
5 namespace node {
6
7 using v8::FunctionCallbackInfo;
8 using v8::FunctionTemplate;
9 using v8::Local;
10 using v8::Map;
11 using v8::Number;
12 using v8::ObjectTemplate;
13 using v8::String;
14 using v8::Value;
15
Histogram(int64_t lowest,int64_t highest,int figures)16 Histogram::Histogram(int64_t lowest, int64_t highest, int figures) {
17 hdr_histogram* histogram;
18 CHECK_EQ(0, hdr_init(lowest, highest, figures, &histogram));
19 histogram_.reset(histogram);
20 }
21
HistogramBase(Environment * env,v8::Local<v8::Object> wrap,int64_t lowest,int64_t highest,int figures)22 HistogramBase::HistogramBase(
23 Environment* env,
24 v8::Local<v8::Object> wrap,
25 int64_t lowest,
26 int64_t highest,
27 int figures)
28 : BaseObject(env, wrap),
29 Histogram(lowest, highest, figures) {
30 MakeWeak();
31 }
32
MemoryInfo(MemoryTracker * tracker) const33 void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
34 tracker->TrackFieldWithSize("histogram", GetMemorySize());
35 }
36
GetMin(const FunctionCallbackInfo<Value> & args)37 void HistogramBase::GetMin(const FunctionCallbackInfo<Value>& args) {
38 HistogramBase* histogram;
39 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
40 double value = static_cast<double>(histogram->Min());
41 args.GetReturnValue().Set(value);
42 }
43
GetMax(const FunctionCallbackInfo<Value> & args)44 void HistogramBase::GetMax(const FunctionCallbackInfo<Value>& args) {
45 HistogramBase* histogram;
46 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
47 double value = static_cast<double>(histogram->Max());
48 args.GetReturnValue().Set(value);
49 }
50
GetMean(const FunctionCallbackInfo<Value> & args)51 void HistogramBase::GetMean(const FunctionCallbackInfo<Value>& args) {
52 HistogramBase* histogram;
53 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
54 args.GetReturnValue().Set(histogram->Mean());
55 }
56
GetExceeds(const FunctionCallbackInfo<Value> & args)57 void HistogramBase::GetExceeds(const FunctionCallbackInfo<Value>& args) {
58 HistogramBase* histogram;
59 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
60 double value = static_cast<double>(histogram->Exceeds());
61 args.GetReturnValue().Set(value);
62 }
63
GetStddev(const FunctionCallbackInfo<Value> & args)64 void HistogramBase::GetStddev(const FunctionCallbackInfo<Value>& args) {
65 HistogramBase* histogram;
66 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
67 args.GetReturnValue().Set(histogram->Stddev());
68 }
69
GetPercentile(const FunctionCallbackInfo<Value> & args)70 void HistogramBase::GetPercentile(
71 const FunctionCallbackInfo<Value>& args) {
72 HistogramBase* histogram;
73 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
74 CHECK(args[0]->IsNumber());
75 double percentile = args[0].As<Number>()->Value();
76 args.GetReturnValue().Set(histogram->Percentile(percentile));
77 }
78
GetPercentiles(const FunctionCallbackInfo<Value> & args)79 void HistogramBase::GetPercentiles(
80 const FunctionCallbackInfo<Value>& args) {
81 Environment* env = Environment::GetCurrent(args);
82 HistogramBase* histogram;
83 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
84 CHECK(args[0]->IsMap());
85 Local<Map> map = args[0].As<Map>();
86 histogram->Percentiles([map, env](double key, double value) {
87 map->Set(
88 env->context(),
89 Number::New(env->isolate(), key),
90 Number::New(env->isolate(), value)).IsEmpty();
91 });
92 }
93
DoReset(const FunctionCallbackInfo<Value> & args)94 void HistogramBase::DoReset(const FunctionCallbackInfo<Value>& args) {
95 HistogramBase* histogram;
96 ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
97 histogram->ResetState();
98 }
99
New(Environment * env,int64_t lowest,int64_t highest,int figures)100 BaseObjectPtr<HistogramBase> HistogramBase::New(
101 Environment* env,
102 int64_t lowest,
103 int64_t highest,
104 int figures) {
105 CHECK_LE(lowest, highest);
106 CHECK_GT(figures, 0);
107 v8::Local<v8::Object> obj;
108 auto tmpl = env->histogram_instance_template();
109 if (!tmpl->NewInstance(env->context()).ToLocal(&obj))
110 return {};
111
112 return MakeDetachedBaseObject<HistogramBase>(
113 env, obj, lowest, highest, figures);
114 }
115
Initialize(Environment * env)116 void HistogramBase::Initialize(Environment* env) {
117 // Guard against multiple initializations
118 if (!env->histogram_instance_template().IsEmpty())
119 return;
120
121 Local<FunctionTemplate> histogram = FunctionTemplate::New(env->isolate());
122 Local<String> classname = FIXED_ONE_BYTE_STRING(env->isolate(), "Histogram");
123 histogram->SetClassName(classname);
124
125 Local<ObjectTemplate> histogramt =
126 histogram->InstanceTemplate();
127
128 histogramt->SetInternalFieldCount(1);
129 env->SetProtoMethod(histogram, "exceeds", HistogramBase::GetExceeds);
130 env->SetProtoMethod(histogram, "min", HistogramBase::GetMin);
131 env->SetProtoMethod(histogram, "max", HistogramBase::GetMax);
132 env->SetProtoMethod(histogram, "mean", HistogramBase::GetMean);
133 env->SetProtoMethod(histogram, "stddev", HistogramBase::GetStddev);
134 env->SetProtoMethod(histogram, "percentile", HistogramBase::GetPercentile);
135 env->SetProtoMethod(histogram, "percentiles", HistogramBase::GetPercentiles);
136 env->SetProtoMethod(histogram, "reset", HistogramBase::DoReset);
137
138 env->set_histogram_instance_template(histogramt);
139 }
140
141 } // namespace node
142