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