// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0
///|
/// A non-atomic shard of a counter. Increments land in the shard and are added
/// to the shared counter on `flush`, which is the local accumulation the Rust
/// client offers; it keeps a hot path off the shared value without requiring
/// thread-local storage.
pub struct LocalCounter {
priv counter : Counter
priv mut value : Double
}
///|
/// A shard of this counter. Many shards may feed one counter; each flushes its
/// own accumulations.
pub fn Counter::shard(self : Counter) -> LocalCounter {
{ counter: self, value: 0.0, }
}
///|
/// Increase the shard by `by`.
pub fn LocalCounter::inc(
self : LocalCounter,
by~ : Double = 1.0,
) -> Unit raise Refused {
if by < 0.0 {
raise Refused("counter can only increase, got " + by.to_string())
}
self.value = self.value + by
}
///|
/// The shard's unflushed value.
pub fn LocalCounter::get(self : LocalCounter) -> Double {
self.value
}
///|
/// Drop the unflushed value.
pub fn LocalCounter::reset(self : LocalCounter) -> Unit {
self.value = 0.0
}
///|
/// Add the shard's value to the shared counter and clear the shard.
pub fn LocalCounter::flush(self : LocalCounter) -> Unit {
if self.value != 0.0 {
self.counter.accrue(self.value)
self.value = 0.0
}
}
///|
pub impl Metric for LocalCounter with fn kind(_self) {
Kind::Counter
}
///|
pub impl Metric for LocalCounter with fn points(self) {
self.flush()
Metric::points(self.counter)
}
///|
pub extend LocalCounter with Metric::{kind, points}