%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/histogram.cc |
#include "histogram.h" // NOLINT(build/include_inline)
#include "base_object-inl.h"
#include "histogram-inl.h"
#include "memory_tracker-inl.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "util.h"
namespace node {
using v8::BigInt;
using v8::CFunction;
using v8::Context;
using v8::FastApiCallbackOptions;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::Map;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint32;
using v8::Value;
Histogram::Histogram(const Options& options) {
hdr_histogram* histogram;
CHECK_EQ(0, hdr_init(options.lowest,
options.highest,
options.figures,
&histogram));
histogram_.reset(histogram);
}
void Histogram::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackFieldWithSize("histogram", GetMemorySize());
}
HistogramImpl::HistogramImpl(const Histogram::Options& options)
: histogram_(new Histogram(options)) {}
HistogramImpl::HistogramImpl(std::shared_ptr<Histogram> histogram)
: histogram_(std::move(histogram)) {}
CFunction HistogramImpl::fast_reset_(
CFunction::Make(&HistogramImpl::FastReset));
CFunction HistogramImpl::fast_get_count_(
CFunction::Make(&HistogramImpl::FastGetCount));
CFunction HistogramImpl::fast_get_min_(
CFunction::Make(&HistogramImpl::FastGetMin));
CFunction HistogramImpl::fast_get_max_(
CFunction::Make(&HistogramImpl::FastGetMax));
CFunction HistogramImpl::fast_get_mean_(
CFunction::Make(&HistogramImpl::FastGetMean));
CFunction HistogramImpl::fast_get_exceeds_(
CFunction::Make(&HistogramImpl::FastGetExceeds));
CFunction HistogramImpl::fast_get_stddev_(
CFunction::Make(&HistogramImpl::FastGetStddev));
CFunction HistogramImpl::fast_get_percentile_(
CFunction::Make(&HistogramImpl::FastGetPercentile));
CFunction HistogramBase::fast_record_(
CFunction::Make(&HistogramBase::FastRecord));
CFunction HistogramBase::fast_record_delta_(
CFunction::Make(&HistogramBase::FastRecordDelta));
CFunction IntervalHistogram::fast_start_(
CFunction::Make(&IntervalHistogram::FastStart));
CFunction IntervalHistogram::fast_stop_(
CFunction::Make(&IntervalHistogram::FastStop));
void HistogramImpl::AddMethods(Isolate* isolate, Local<FunctionTemplate> tmpl) {
// TODO(@jasnell): The bigint API variations do not yet support fast
// variations since v8 will not return a bigint value from a fast method.
SetProtoMethodNoSideEffect(isolate, tmpl, "countBigInt", GetCountBigInt);
SetProtoMethodNoSideEffect(isolate, tmpl, "exceedsBigInt", GetExceedsBigInt);
SetProtoMethodNoSideEffect(isolate, tmpl, "minBigInt", GetMinBigInt);
SetProtoMethodNoSideEffect(isolate, tmpl, "maxBigInt", GetMaxBigInt);
SetProtoMethodNoSideEffect(
isolate, tmpl, "percentileBigInt", GetPercentileBigInt);
SetProtoMethodNoSideEffect(isolate, tmpl, "percentiles", GetPercentiles);
SetProtoMethodNoSideEffect(
isolate, tmpl, "percentilesBigInt", GetPercentilesBigInt);
auto instance = tmpl->InstanceTemplate();
SetFastMethodNoSideEffect(
isolate, instance, "count", GetCount, &fast_get_count_);
SetFastMethodNoSideEffect(
isolate, instance, "exceeds", GetExceeds, &fast_get_exceeds_);
SetFastMethodNoSideEffect(isolate, instance, "min", GetMin, &fast_get_min_);
SetFastMethodNoSideEffect(isolate, instance, "max", GetMax, &fast_get_max_);
SetFastMethodNoSideEffect(
isolate, instance, "mean", GetMean, &fast_get_mean_);
SetFastMethodNoSideEffect(
isolate, instance, "stddev", GetStddev, &fast_get_stddev_);
SetFastMethodNoSideEffect(
isolate, instance, "percentile", GetPercentile, &fast_get_percentile_);
SetFastMethod(isolate, instance, "reset", DoReset, &fast_reset_);
}
void HistogramImpl::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
static bool is_registerd = false;
if (is_registerd) return;
registry->Register(GetCount);
registry->Register(GetCountBigInt);
registry->Register(GetExceeds);
registry->Register(GetExceedsBigInt);
registry->Register(GetMin);
registry->Register(GetMinBigInt);
registry->Register(GetMax);
registry->Register(GetMaxBigInt);
registry->Register(GetMean);
registry->Register(GetStddev);
registry->Register(GetPercentile);
registry->Register(GetPercentileBigInt);
registry->Register(GetPercentiles);
registry->Register(GetPercentilesBigInt);
registry->Register(DoReset);
registry->Register(fast_reset_.GetTypeInfo());
registry->Register(fast_get_count_.GetTypeInfo());
registry->Register(fast_get_min_.GetTypeInfo());
registry->Register(fast_get_max_.GetTypeInfo());
registry->Register(fast_get_mean_.GetTypeInfo());
registry->Register(fast_get_exceeds_.GetTypeInfo());
registry->Register(fast_get_stddev_.GetTypeInfo());
registry->Register(fast_get_percentile_.GetTypeInfo());
registry->Register(FastReset);
registry->Register(FastGetCount);
registry->Register(FastGetMin);
registry->Register(FastGetMax);
registry->Register(FastGetMean);
registry->Register(FastGetExceeds);
registry->Register(FastGetStddev);
registry->Register(FastGetPercentile);
is_registerd = true;
}
HistogramBase::HistogramBase(
Environment* env,
Local<Object> wrap,
const Histogram::Options& options)
: BaseObject(env, wrap),
HistogramImpl(options) {
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
}
HistogramBase::HistogramBase(
Environment* env,
Local<Object> wrap,
std::shared_ptr<Histogram> histogram)
: BaseObject(env, wrap),
HistogramImpl(std::move(histogram)) {
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
}
void HistogramBase::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("histogram", histogram());
}
void HistogramBase::RecordDelta(const FunctionCallbackInfo<Value>& args) {
HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
(*histogram)->RecordDelta();
}
void HistogramBase::FastRecordDelta(Local<Value> receiver) {
HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
(*histogram)->RecordDelta();
}
void HistogramBase::Record(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
bool lossless = true;
int64_t value = args[0]->IsBigInt()
? args[0].As<BigInt>()->Int64Value(&lossless)
: static_cast<int64_t>(args[0].As<Number>()->Value());
if (!lossless || value < 1)
return THROW_ERR_OUT_OF_RANGE(env, "value is out of range");
HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
(*histogram)->Record(value);
}
void HistogramBase::FastRecord(Local<Value> receiver,
const int64_t value,
FastApiCallbackOptions& options) {
if (value < 1) {
options.fallback = true;
return;
}
HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
(*histogram)->Record(value);
}
void HistogramBase::Add(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramBase* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
CHECK(GetConstructorTemplate(env->isolate_data())->HasInstance(args[0]));
HistogramBase* other;
ASSIGN_OR_RETURN_UNWRAP(&other, args[0]);
double count = (*histogram)->Add(*(other->histogram()));
args.GetReturnValue().Set(count);
}
BaseObjectPtr<HistogramBase> HistogramBase::Create(
Environment* env,
const Histogram::Options& options) {
Local<Object> obj;
if (!GetConstructorTemplate(env->isolate_data())
->InstanceTemplate()
->NewInstance(env->context())
.ToLocal(&obj)) {
return BaseObjectPtr<HistogramBase>();
}
return MakeBaseObject<HistogramBase>(env, obj, options);
}
BaseObjectPtr<HistogramBase> HistogramBase::Create(
Environment* env,
std::shared_ptr<Histogram> histogram) {
Local<Object> obj;
if (!GetConstructorTemplate(env->isolate_data())
->InstanceTemplate()
->NewInstance(env->context())
.ToLocal(&obj)) {
return BaseObjectPtr<HistogramBase>();
}
return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
}
void HistogramBase::New(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
Environment* env = Environment::GetCurrent(args);
CHECK_IMPLIES(!args[0]->IsNumber(), args[0]->IsBigInt());
CHECK_IMPLIES(!args[1]->IsNumber(), args[1]->IsBigInt());
CHECK(args[2]->IsUint32());
int64_t lowest = 1;
int64_t highest = std::numeric_limits<int64_t>::max();
bool lossless_ignored;
if (args[0]->IsNumber()) {
lowest = args[0].As<Integer>()->Value();
} else if (args[0]->IsBigInt()) {
lowest = args[0].As<BigInt>()->Int64Value(&lossless_ignored);
}
if (args[1]->IsNumber()) {
highest = args[1].As<Integer>()->Value();
} else if (args[1]->IsBigInt()) {
highest = args[1].As<BigInt>()->Int64Value(&lossless_ignored);
}
int32_t figures = args[2].As<Uint32>()->Value();
new HistogramBase(env, args.This(), Histogram::Options {
lowest, highest, figures
});
}
Local<FunctionTemplate> HistogramBase::GetConstructorTemplate(
IsolateData* isolate_data) {
Local<FunctionTemplate> tmpl = isolate_data->histogram_ctor_template();
if (tmpl.IsEmpty()) {
Isolate* isolate = isolate_data->isolate();
tmpl = NewFunctionTemplate(isolate, New);
Local<String> classname = FIXED_ONE_BYTE_STRING(isolate, "Histogram");
tmpl->SetClassName(classname);
auto instance = tmpl->InstanceTemplate();
instance->SetInternalFieldCount(HistogramImpl::kInternalFieldCount);
SetFastMethod(isolate, instance, "record", Record, &fast_record_);
SetFastMethod(
isolate, instance, "recordDelta", RecordDelta, &fast_record_delta_);
SetProtoMethod(isolate, tmpl, "add", Add);
HistogramImpl::AddMethods(isolate, tmpl);
isolate_data->set_histogram_ctor_template(tmpl);
}
return tmpl;
}
void HistogramBase::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(New);
registry->Register(Add);
registry->Register(Record);
registry->Register(RecordDelta);
registry->Register(fast_record_.GetTypeInfo());
registry->Register(fast_record_delta_.GetTypeInfo());
registry->Register(FastRecord);
registry->Register(FastRecordDelta);
HistogramImpl::RegisterExternalReferences(registry);
}
void HistogramBase::Initialize(IsolateData* isolate_data,
Local<ObjectTemplate> target) {
SetConstructorFunction(isolate_data->isolate(),
target,
"Histogram",
GetConstructorTemplate(isolate_data),
SetConstructorFunctionFlag::NONE);
}
BaseObjectPtr<BaseObject> HistogramBase::HistogramTransferData::Deserialize(
Environment* env,
Local<Context> context,
std::unique_ptr<worker::TransferData> self) {
return Create(env, std::move(histogram_));
}
std::unique_ptr<worker::TransferData> HistogramBase::CloneForMessaging() const {
return std::make_unique<HistogramTransferData>(this);
}
void HistogramBase::HistogramTransferData::MemoryInfo(
MemoryTracker* tracker) const {
tracker->TrackField("histogram", histogram_);
}
Local<FunctionTemplate> IntervalHistogram::GetConstructorTemplate(
Environment* env) {
Local<FunctionTemplate> tmpl = env->intervalhistogram_constructor_template();
if (tmpl.IsEmpty()) {
Isolate* isolate = env->isolate();
tmpl = NewFunctionTemplate(isolate, nullptr);
tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
tmpl->SetClassName(OneByteString(isolate, "Histogram"));
auto instance = tmpl->InstanceTemplate();
instance->SetInternalFieldCount(HistogramImpl::kInternalFieldCount);
HistogramImpl::AddMethods(isolate, tmpl);
SetFastMethod(isolate, instance, "start", Start, &fast_start_);
SetFastMethod(isolate, instance, "stop", Stop, &fast_stop_);
env->set_intervalhistogram_constructor_template(tmpl);
}
return tmpl;
}
void IntervalHistogram::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(Start);
registry->Register(Stop);
registry->Register(fast_start_.GetTypeInfo());
registry->Register(fast_stop_.GetTypeInfo());
registry->Register(FastStart);
registry->Register(FastStop);
HistogramImpl::RegisterExternalReferences(registry);
}
IntervalHistogram::IntervalHistogram(
Environment* env,
Local<Object> wrap,
AsyncWrap::ProviderType type,
int32_t interval,
std::function<void(Histogram&)> on_interval,
const Histogram::Options& options)
: HandleWrap(
env,
wrap,
reinterpret_cast<uv_handle_t*>(&timer_),
type),
HistogramImpl(options),
interval_(interval),
on_interval_(std::move(on_interval)) {
MakeWeak();
wrap->SetAlignedPointerInInternalField(
HistogramImpl::InternalFields::kImplField,
static_cast<HistogramImpl*>(this));
uv_timer_init(env->event_loop(), &timer_);
}
BaseObjectPtr<IntervalHistogram> IntervalHistogram::Create(
Environment* env,
int32_t interval,
std::function<void(Histogram&)> on_interval,
const Histogram::Options& options) {
Local<Object> obj;
if (!GetConstructorTemplate(env)
->InstanceTemplate()
->NewInstance(env->context()).ToLocal(&obj)) {
return BaseObjectPtr<IntervalHistogram>();
}
return MakeBaseObject<IntervalHistogram>(
env,
obj,
AsyncWrap::PROVIDER_ELDHISTOGRAM,
interval,
std::move(on_interval),
options);
}
void IntervalHistogram::TimerCB(uv_timer_t* handle) {
IntervalHistogram* histogram =
ContainerOf(&IntervalHistogram::timer_, handle);
Histogram* h = histogram->histogram().get();
histogram->on_interval_(*h);
}
void IntervalHistogram::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("histogram", histogram());
}
void IntervalHistogram::OnStart(StartFlags flags) {
if (enabled_ || IsHandleClosing()) return;
enabled_ = true;
if (flags == StartFlags::RESET)
histogram()->Reset();
uv_timer_start(&timer_, TimerCB, interval_, interval_);
uv_unref(reinterpret_cast<uv_handle_t*>(&timer_));
}
void IntervalHistogram::OnStop() {
if (!enabled_ || IsHandleClosing()) return;
enabled_ = false;
uv_timer_stop(&timer_);
}
void IntervalHistogram::Start(const FunctionCallbackInfo<Value>& args) {
IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE);
}
void IntervalHistogram::FastStart(Local<Value> receiver, bool reset) {
IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
histogram->OnStart(reset ? StartFlags::RESET : StartFlags::NONE);
}
void IntervalHistogram::Stop(const FunctionCallbackInfo<Value>& args) {
IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder());
histogram->OnStop();
}
void IntervalHistogram::FastStop(Local<Value> receiver) {
IntervalHistogram* histogram;
ASSIGN_OR_RETURN_UNWRAP(&histogram, receiver);
histogram->OnStop();
}
void HistogramImpl::GetCount(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
double value = static_cast<double>((*histogram)->Count());
args.GetReturnValue().Set(value);
}
void HistogramImpl::GetCountBigInt(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set(
BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count()));
}
void HistogramImpl::GetMin(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
double value = static_cast<double>((*histogram)->Min());
args.GetReturnValue().Set(value);
}
void HistogramImpl::GetMinBigInt(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min()));
}
void HistogramImpl::GetMax(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
double value = static_cast<double>((*histogram)->Max());
args.GetReturnValue().Set(value);
}
void HistogramImpl::GetMaxBigInt(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Max()));
}
void HistogramImpl::GetMean(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set((*histogram)->Mean());
}
void HistogramImpl::GetExceeds(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
double value = static_cast<double>((*histogram)->Exceeds());
args.GetReturnValue().Set(value);
}
void HistogramImpl::GetExceedsBigInt(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set(
BigInt::New(env->isolate(), (*histogram)->Exceeds()));
}
void HistogramImpl::GetStddev(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
args.GetReturnValue().Set((*histogram)->Stddev());
}
void HistogramImpl::GetPercentile(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
CHECK(args[0]->IsNumber());
double percentile = args[0].As<Number>()->Value();
double value = static_cast<double>((*histogram)->Percentile(percentile));
args.GetReturnValue().Set(value);
}
void HistogramImpl::GetPercentileBigInt(
const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
CHECK(args[0]->IsNumber());
double percentile = args[0].As<Number>()->Value();
int64_t value = (*histogram)->Percentile(percentile);
args.GetReturnValue().Set(BigInt::New(env->isolate(), value));
}
void HistogramImpl::GetPercentiles(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
CHECK(args[0]->IsMap());
Local<Map> map = args[0].As<Map>();
(*histogram)->Percentiles([map, env](double key, int64_t value) {
USE(map->Set(
env->context(),
Number::New(env->isolate(), key),
Number::New(env->isolate(), static_cast<double>(value))));
});
}
void HistogramImpl::GetPercentilesBigInt(
const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
CHECK(args[0]->IsMap());
Local<Map> map = args[0].As<Map>();
(*histogram)->Percentiles([map, env](double key, int64_t value) {
USE(map->Set(
env->context(),
Number::New(env->isolate(), key),
BigInt::New(env->isolate(), value)));
});
}
void HistogramImpl::DoReset(const FunctionCallbackInfo<Value>& args) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder());
(*histogram)->Reset();
}
void HistogramImpl::FastReset(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
(*histogram)->Reset();
}
double HistogramImpl::FastGetCount(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Count());
}
double HistogramImpl::FastGetMin(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Min());
}
double HistogramImpl::FastGetMax(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Max());
}
double HistogramImpl::FastGetMean(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return (*histogram)->Mean();
}
double HistogramImpl::FastGetExceeds(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Exceeds());
}
double HistogramImpl::FastGetStddev(Local<Value> receiver) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return (*histogram)->Stddev();
}
double HistogramImpl::FastGetPercentile(Local<Value> receiver,
const double percentile) {
HistogramImpl* histogram = HistogramImpl::FromJSObject(receiver);
return static_cast<double>((*histogram)->Percentile(percentile));
}
HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
auto obj = value.As<Object>();
DCHECK_GE(obj->InternalFieldCount(), HistogramImpl::kInternalFieldCount);
return static_cast<HistogramImpl*>(
obj->GetAlignedPointerFromInternalField(HistogramImpl::kImplField));
}
std::unique_ptr<worker::TransferData>
IntervalHistogram::CloneForMessaging() const {
return std::make_unique<HistogramBase::HistogramTransferData>(histogram());
}
} // namespace node