Files
bun.sh/src/bun.js/node/node_perf_hooks_histogram_binding.zig
2024-06-28 18:17:32 -07:00

182 lines
5.8 KiB
Zig

const std = @import("std");
const bun = @import("root").bun;
const meta = bun.meta;
const JSC = bun.JSC;
const JSValue = JSC.JSValue;
pub const RecordableHistogram = struct {
pub usingnamespace JSC.Codegen.JSRecordableHistogram;
min: u64 = 1,
max: u64 = 2,
mean: f64 = 3, // todo: make this optional
exceeds: u64 = 4,
stddev: f64 = 5, // todo: make this optional
count: u64 = 6,
percentilesInternal: std.AutoHashMap(f32, f32) = std.AutoHashMap(f32, f32).init(bun.default_allocator),
const This = @This();
//todo: these should also be explicit functions, IE both .max and .max() work
pub const min = getter(.min);
pub const max = getter(.max);
pub const mean = getter(.mean);
pub const exceeds = getter(.exceeds);
pub const stddev = getter(.stddev);
pub const count = getter(.count);
// we need a special getter for percentiles because it's a hashmap
pub const percentiles = @as(
PropertyGetter,
struct {
pub fn callback(this: *This, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue {
_ = this;
_ = globalThis;
return .undefined;
}
}.callback,
);
pub fn record(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn recordDelta(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn add(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
const args = callframe.arguments(1).slice();
if (args.len != 1) {
globalThis.throwInvalidArguments("Expected 1 argument", .{});
return .zero;
}
// todo: make below work
// const other = args[0].to(RecordableHistogram);
// _ = other;
return .undefined;
}
pub fn reset(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn countBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn minBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn maxBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn exceedsBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn percentile(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
const args = callframe.arguments(1).slice();
if (args.len != 1) {
globalThis.throwInvalidArguments("Expected 1 argument", .{});
return .zero;
}
// todo: make below work
// const percent = args[0].to(f64);
// _ = percent;
return .undefined;
}
pub fn percentileBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
const args = callframe.arguments(1).slice();
if (args.len != 1) {
globalThis.throwInvalidArguments("Expected 1 argument", .{});
return .zero;
}
// todo: make below work
// const percent = args[0].to(f64);
// _ = percent;
return .undefined;
}
pub fn percentilesBigInt(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
pub fn toJSON(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
_ = this;
_ = globalThis;
_ = callframe;
return .undefined;
}
const PropertyGetter = fn (this: *This, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
fn getter(comptime field: meta.FieldEnum(This)) PropertyGetter {
return struct {
pub fn callback(this: *This, globalObject: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
const v = @field(this, @tagName(field));
return globalObject.toJS(v, .temporary);
}
}.callback;
}
pub const value = getter(.value);
// since we create this with bun.new, we need to have it be destroyable
// our node.classes.ts has finalize=true to generate the call to finalize
pub fn finalize(this: *This) callconv(.C) void {
this.percentilesInternal.deinit();
bun.destroy(this);
}
};
fn createHistogram(globalThis: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
return bun.new(RecordableHistogram, .{}).toJS(globalThis);
}
pub fn createPerfHooksHistogramBinding(global: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
const histogram = JSC.JSValue.createEmptyObject(global, 1);
histogram.put(
global,
bun.String.init("createHistogram"),
JSC.JSFunction.create(
global,
"createHistogram",
&createHistogram,
3, // function length
.{},
),
);
return histogram;
}