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