///|
/// Private C-owned scalar state. `moonbit_make_external_object` owns its
/// lifetime, so the pthread mutex is finalized with the enclosing MoonBit
/// object instead of leaking as an unmanaged external pointer.
#cfg(target="native")
pub type NativeScalarCell
///|
#cfg(target="native")
extern "C" fn native_scalar_new(initial : Double) -> NativeScalarCell = "moon_prometheus_scalar_new"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeScalarCell::get(self : NativeScalarCell) -> Double = "moon_prometheus_scalar_get"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeScalarCell::set(
self : NativeScalarCell,
value : Double,
) -> Unit = "moon_prometheus_scalar_set"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeScalarCell::add(
self : NativeScalarCell,
delta : Double,
) -> Unit = "moon_prometheus_scalar_add"
///|
/// Native scalar storage uses one pthread mutex per metric object.
#cfg(target="native")
pub struct ScalarCell {
native : NativeScalarCell
}
///|
#cfg(target="native")
pub fn ScalarCell::new(initial : Double) -> ScalarCell {
{ native: native_scalar_new(initial) }
}
///|
#cfg(target="native")
pub fn ScalarCell::get(self : ScalarCell) -> Double {
self.native.get()
}
///|
#cfg(target="native")
pub fn ScalarCell::set(self : ScalarCell, value : Double) -> Unit {
self.native.set(value)
}
///|
#cfg(target="native")
pub fn ScalarCell::add(self : ScalarCell, delta : Double) -> Unit {
self.native.add(delta)
}
///|
/// C-owned mutex object used to guard native Vec and Registry tables. It has
/// no user-visible lock type in the facade and is finalized automatically.
#cfg(target="native")
pub type NativeMutex
///|
#cfg(target="native")
extern "C" fn native_mutex_new() -> NativeMutex = "moon_prometheus_mutex_new"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeMutex::lock(self : NativeMutex) -> Unit = "moon_prometheus_mutex_lock"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeMutex::unlock(self : NativeMutex) -> Unit = "moon_prometheus_mutex_unlock"
///|
#cfg(target="native")
pub struct Mutex {
native : NativeMutex
}
///|
#cfg(target="native")
pub fn Mutex::new() -> Mutex {
{ native: native_mutex_new() }
}
///|
#cfg(target="native")
pub fn Mutex::lock(self : Mutex) -> Unit {
self.native.lock()
}
///|
#cfg(target="native")
pub fn Mutex::unlock(self : Mutex) -> Unit {
self.native.unlock()
}
///|
#cfg(target="native")
pub type NativeHistogramCell
///|
#cfg(target="native")
priv type NativeHistogramSnapshot
///|
#cfg(target="native")
extern "C" fn native_histogram_new(length : Int) -> NativeHistogramCell = "moon_prometheus_histogram_new"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeHistogramCell::observe(
self : NativeHistogramCell,
first_bucket : Int,
value : Double,
) -> Unit = "moon_prometheus_histogram_observe"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeHistogramCell::copy_snapshot(
self : NativeHistogramCell,
) -> NativeHistogramSnapshot = "moon_prometheus_histogram_copy_snapshot"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeHistogramSnapshot::count_at(
self : NativeHistogramSnapshot,
index : Int,
) -> Int64 = "moon_prometheus_histogram_snapshot_count_at"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeHistogramSnapshot::count(
self : NativeHistogramSnapshot,
) -> Int64 = "moon_prometheus_histogram_snapshot_count"
///|
#cfg(target="native")
#borrow(self)
extern "C" fn NativeHistogramSnapshot::sum(
self : NativeHistogramSnapshot,
) -> Double = "moon_prometheus_histogram_snapshot_sum"
///|
/// Native histogram storage keeps the mutex-protected counters in C while
/// retaining immutable bucket boundaries in MoonBit for bucket lookup.
#cfg(target="native")
pub struct HistogramCell {
boundaries : Array[Double]
native : NativeHistogramCell
}
///|
#cfg(target="native")
pub fn HistogramCell::new(boundaries : Array[Double]) -> HistogramCell {
{
boundaries: boundaries.copy(),
native: native_histogram_new(boundaries.length()),
}
}
///|
#cfg(target="native")
fn HistogramCell::first_bucket(self : HistogramCell, value : Double) -> Int {
for index, boundary in self.boundaries {
if value <= boundary {
return index
}
}
self.boundaries.length()
}
///|
#cfg(target="native")
pub fn HistogramCell::observe(self : HistogramCell, value : Double) -> Unit {
self.native.observe(self.first_bucket(value), value)
}
///|
#cfg(target="native")
pub fn HistogramCell::snapshot(self : HistogramCell) -> HistogramCellSnapshot {
let native_snapshot = self.native.copy_snapshot()
let counts : Array[Int64] = []
for index in 0..