• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_HISTOGRAM_H_
2 #define SRC_HISTOGRAM_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include "hdr_histogram.h"
7 #include "base_object.h"
8 #include "memory_tracker.h"
9 #include "node_messaging.h"
10 #include "util.h"
11 #include "v8.h"
12 #include "uv.h"
13 
14 #include <functional>
15 #include <limits>
16 #include <map>
17 #include <string>
18 
19 namespace node {
20 
21 constexpr int kDefaultHistogramFigures = 3;
22 
23 class Histogram : public MemoryRetainer {
24  public:
25   Histogram(
26       int64_t lowest = 1,
27       int64_t highest = std::numeric_limits<int64_t>::max(),
28       int figures = kDefaultHistogramFigures);
29   virtual ~Histogram() = default;
30 
31   inline bool Record(int64_t value);
32   inline void Reset();
33   inline int64_t Min();
34   inline int64_t Max();
35   inline double Mean();
36   inline double Stddev();
37   inline double Percentile(double percentile);
Exceeds()38   inline int64_t Exceeds() const { return exceeds_; }
39 
40   inline uint64_t RecordDelta();
41 
42   // Iterator is a function type that takes two doubles as argument, one for
43   // percentile and one for the value at that percentile.
44   template <typename Iterator>
45   inline void Percentiles(Iterator&& fn);
46 
47   inline size_t GetMemorySize() const;
48 
49   void MemoryInfo(MemoryTracker* tracker) const override;
50   SET_MEMORY_INFO_NAME(Histogram)
51   SET_SELF_SIZE(Histogram)
52 
53  private:
54   using HistogramPointer = DeleteFnPtr<hdr_histogram, hdr_close>;
55   HistogramPointer histogram_;
56   int64_t exceeds_ = 0;
57   uint64_t prev_ = 0;
58 
59   Mutex mutex_;
60 };
61 
62 class HistogramImpl {
63  public:
64   HistogramImpl(int64_t lowest, int64_t highest, int figures);
65   explicit HistogramImpl(std::shared_ptr<Histogram> histogram);
66 
67   Histogram* operator->() { return histogram_.get(); }
68 
69  protected:
histogram()70   const std::shared_ptr<Histogram>& histogram() const { return histogram_; }
71 
72  private:
73   std::shared_ptr<Histogram> histogram_;
74 };
75 
76 class HistogramBase : public BaseObject, public HistogramImpl {
77  public:
78   static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
79     Environment* env);
80   static void Initialize(Environment* env, v8::Local<v8::Object> target);
81 
82   static BaseObjectPtr<HistogramBase> Create(
83       Environment* env,
84       int64_t lowest = 1,
85       int64_t highest = std::numeric_limits<int64_t>::max(),
86       int figures = kDefaultHistogramFigures);
87 
88   static BaseObjectPtr<HistogramBase> Create(
89       Environment* env,
90       std::shared_ptr<Histogram> histogram);
91 
92   static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
93 
94   void MemoryInfo(MemoryTracker* tracker) const override;
95   SET_MEMORY_INFO_NAME(HistogramBase)
96   SET_SELF_SIZE(HistogramBase)
97 
98   static void GetMin(const v8::FunctionCallbackInfo<v8::Value>& args);
99   static void GetMax(const v8::FunctionCallbackInfo<v8::Value>& args);
100   static void GetMean(const v8::FunctionCallbackInfo<v8::Value>& args);
101   static void GetExceeds(const v8::FunctionCallbackInfo<v8::Value>& args);
102   static void GetStddev(const v8::FunctionCallbackInfo<v8::Value>& args);
103   static void GetPercentile(
104       const v8::FunctionCallbackInfo<v8::Value>& args);
105   static void GetPercentiles(
106       const v8::FunctionCallbackInfo<v8::Value>& args);
107   static void DoReset(const v8::FunctionCallbackInfo<v8::Value>& args);
108   static void Record(const v8::FunctionCallbackInfo<v8::Value>& args);
109   static void RecordDelta(const v8::FunctionCallbackInfo<v8::Value>& args);
110 
111   HistogramBase(
112       Environment* env,
113       v8::Local<v8::Object> wrap,
114       int64_t lowest = 1,
115       int64_t highest = std::numeric_limits<int64_t>::max(),
116       int figures = kDefaultHistogramFigures);
117 
118   HistogramBase(
119       Environment* env,
120       v8::Local<v8::Object> wrap,
121       std::shared_ptr<Histogram> histogram);
122 
GetTransferMode()123   TransferMode GetTransferMode() const override {
124     return TransferMode::kCloneable;
125   }
126   std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
127 
128   class HistogramTransferData : public worker::TransferData {
129    public:
HistogramTransferData(const HistogramBase * histogram)130     explicit HistogramTransferData(const HistogramBase* histogram)
131         : histogram_(histogram->histogram()) {}
132 
HistogramTransferData(std::shared_ptr<Histogram> histogram)133     explicit HistogramTransferData(std::shared_ptr<Histogram> histogram)
134         : histogram_(std::move(histogram)) {}
135 
136     BaseObjectPtr<BaseObject> Deserialize(
137         Environment* env,
138         v8::Local<v8::Context> context,
139         std::unique_ptr<worker::TransferData> self) override;
140 
141     void MemoryInfo(MemoryTracker* tracker) const override;
142     SET_MEMORY_INFO_NAME(HistogramTransferData)
143     SET_SELF_SIZE(HistogramTransferData)
144 
145    private:
146     std::shared_ptr<Histogram> histogram_;
147   };
148 };
149 
150 class IntervalHistogram : public HandleWrap, public HistogramImpl {
151  public:
152   enum class StartFlags {
153     NONE,
154     RESET
155   };
156 
157   static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
158       Environment* env);
159 
160   static BaseObjectPtr<IntervalHistogram> Create(
161       Environment* env,
162       int64_t lowest = 1,
163       int64_t highest = std::numeric_limits<int64_t>::max(),
164       int figures = kDefaultHistogramFigures);
165 
166   virtual void OnInterval() = 0;
167 
168   void MemoryInfo(MemoryTracker* tracker) const override;
169 
170   IntervalHistogram(
171       Environment* env,
172       v8::Local<v8::Object> wrap,
173       AsyncWrap::ProviderType type,
174       int32_t interval,
175       int64_t lowest = 1,
176       int64_t highest = std::numeric_limits<int64_t>::max(),
177       int figures = kDefaultHistogramFigures);
178 
179   static void GetMin(const v8::FunctionCallbackInfo<v8::Value>& args);
180   static void GetMax(const v8::FunctionCallbackInfo<v8::Value>& args);
181   static void GetMean(const v8::FunctionCallbackInfo<v8::Value>& args);
182   static void GetExceeds(const v8::FunctionCallbackInfo<v8::Value>& args);
183   static void GetStddev(const v8::FunctionCallbackInfo<v8::Value>& args);
184   static void GetPercentile(
185       const v8::FunctionCallbackInfo<v8::Value>& args);
186   static void GetPercentiles(
187       const v8::FunctionCallbackInfo<v8::Value>& args);
188   static void DoReset(const v8::FunctionCallbackInfo<v8::Value>& args);
189   static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
190   static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args);
191 
GetTransferMode()192   TransferMode GetTransferMode() const override {
193     return TransferMode::kCloneable;
194   }
195   std::unique_ptr<worker::TransferData> CloneForMessaging() const override;
196 
197  private:
198   static void TimerCB(uv_timer_t* handle);
199   void OnStart(StartFlags flags = StartFlags::RESET);
200   void OnStop();
201 
202   bool enabled_ = false;
203   int32_t interval_ = 0;
204   uv_timer_t timer_;
205 };
206 
207 }  // namespace node
208 
209 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
210 
211 #endif  // SRC_HISTOGRAM_H_
212