use crate::performance_evidence::{EvidenceCounter, EvidenceGauge, EvidenceHighWaterMark};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct BytePoolEvidence {
active_leases_at_start: u64,
reservation_attempts: EvidenceCounter,
requested_bytes: EvidenceCounter,
free_extents_examined: EvidenceCounter,
free_extent_count_high_water: EvidenceHighWaterMark,
reservations: EvidenceCounter,
exhausted_reservations: EvidenceCounter,
lease_capacity_refusals: EvidenceCounter,
lease_identity_refusals: EvidenceCounter,
inconsistencies: EvidenceCounter,
materializations: EvidenceCounter,
materialized_bytes: EvidenceCounter,
resume_attempts: EvidenceCounter,
resumed_leases: EvidenceCounter,
resume_refusals: EvidenceCounter,
recycle_attempts: EvidenceCounter,
recycled_leases: EvidenceCounter,
recycle_refusals: EvidenceCounter,
released_leases_collected: EvidenceCounter,
active_leases: EvidenceGauge,
}
impl BytePoolEvidence {
pub const fn new() -> Self {
Self::starting_with_active_leases(0)
}
pub const fn starting_with_active_leases(active_leases: u64) -> Self {
Self {
active_leases_at_start: active_leases,
reservation_attempts: EvidenceCounter::new(),
requested_bytes: EvidenceCounter::new(),
free_extents_examined: EvidenceCounter::new(),
free_extent_count_high_water: EvidenceHighWaterMark::new(),
reservations: EvidenceCounter::new(),
exhausted_reservations: EvidenceCounter::new(),
lease_capacity_refusals: EvidenceCounter::new(),
lease_identity_refusals: EvidenceCounter::new(),
inconsistencies: EvidenceCounter::new(),
materializations: EvidenceCounter::new(),
materialized_bytes: EvidenceCounter::new(),
resume_attempts: EvidenceCounter::new(),
resumed_leases: EvidenceCounter::new(),
resume_refusals: EvidenceCounter::new(),
recycle_attempts: EvidenceCounter::new(),
recycled_leases: EvidenceCounter::new(),
recycle_refusals: EvidenceCounter::new(),
released_leases_collected: EvidenceCounter::new(),
active_leases: EvidenceGauge::new(active_leases),
}
}
pub const fn active_leases_at_start(self) -> u64 {
self.active_leases_at_start
}
pub const fn reservation_attempts(self) -> EvidenceCounter {
self.reservation_attempts
}
pub const fn requested_bytes(self) -> EvidenceCounter {
self.requested_bytes
}
pub const fn free_extents_examined(self) -> EvidenceCounter {
self.free_extents_examined
}
pub const fn free_extent_count_high_water(self) -> EvidenceHighWaterMark {
self.free_extent_count_high_water
}
pub const fn reservations(self) -> EvidenceCounter {
self.reservations
}
pub const fn exhausted_reservations(self) -> EvidenceCounter {
self.exhausted_reservations
}
pub const fn lease_capacity_refusals(self) -> EvidenceCounter {
self.lease_capacity_refusals
}
pub const fn lease_identity_refusals(self) -> EvidenceCounter {
self.lease_identity_refusals
}
pub const fn inconsistencies(self) -> EvidenceCounter {
self.inconsistencies
}
pub const fn materializations(self) -> EvidenceCounter {
self.materializations
}
pub const fn materialized_bytes(self) -> EvidenceCounter {
self.materialized_bytes
}
pub const fn resume_attempts(self) -> EvidenceCounter {
self.resume_attempts
}
pub const fn resumed_leases(self) -> EvidenceCounter {
self.resumed_leases
}
pub const fn resume_refusals(self) -> EvidenceCounter {
self.resume_refusals
}
pub const fn recycle_attempts(self) -> EvidenceCounter {
self.recycle_attempts
}
pub const fn recycled_leases(self) -> EvidenceCounter {
self.recycled_leases
}
pub const fn recycle_refusals(self) -> EvidenceCounter {
self.recycle_refusals
}
pub const fn released_leases_collected(self) -> EvidenceCounter {
self.released_leases_collected
}
pub const fn active_leases(self) -> EvidenceGauge {
self.active_leases
}
pub fn valid(&self) -> bool {
self.reservation_attempts.valid()
&& self.requested_bytes.valid()
&& self.free_extents_examined.valid()
&& self.reservations.valid()
&& self.exhausted_reservations.valid()
&& self.lease_capacity_refusals.valid()
&& self.lease_identity_refusals.valid()
&& self.inconsistencies.valid()
&& self.materializations.valid()
&& self.materialized_bytes.valid()
&& self.resume_attempts.valid()
&& self.resumed_leases.valid()
&& self.resume_refusals.valid()
&& self.recycle_attempts.valid()
&& self.recycled_leases.valid()
&& self.recycle_refusals.valid()
&& self.released_leases_collected.valid()
&& self.active_leases.valid()
}
pub(crate) fn record_reservation_attempt(
&mut self,
requested_bytes: usize,
free_extent_count: usize,
) {
self.reservation_attempts.record(1);
self.requested_bytes.record_usize(requested_bytes);
self.free_extents_examined.record_usize(free_extent_count);
self.free_extent_count_high_water
.observe_usize(free_extent_count);
}
pub(crate) fn record_reservation(&mut self) {
self.reservations.record(1);
}
pub(crate) fn record_exhaustion(&mut self) {
self.exhausted_reservations.record(1);
}
pub(crate) fn record_lease_capacity_refusal(&mut self) {
self.lease_capacity_refusals.record(1);
}
pub(crate) fn record_lease_identity_refusal(&mut self) {
self.lease_identity_refusals.record(1);
}
pub(crate) fn record_inconsistency(&mut self) {
self.inconsistencies.record(1);
}
pub(crate) fn record_materialization(&mut self, byte_count: usize) {
self.materializations.record(1);
self.materialized_bytes.record_usize(byte_count);
self.active_leases.increase(1);
}
pub(crate) fn record_resume_attempt(&mut self) {
self.resume_attempts.record(1);
}
pub(crate) fn record_resumed(&mut self) {
self.resumed_leases.record(1);
}
pub(crate) fn record_resume_refusal(&mut self) {
self.resume_refusals.record(1);
}
pub(crate) fn record_recycle_attempt(&mut self) {
self.recycle_attempts.record(1);
}
pub(crate) fn record_recycled(&mut self) {
self.recycled_leases.record(1);
}
pub(crate) fn record_recycle_refusal(&mut self) {
self.recycle_refusals.record(1);
}
pub(crate) fn record_released_lease(&mut self) {
self.released_leases_collected.record(1);
self.active_leases.decrease(1);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn any_saturated_counter_invalidates_the_complete_pool_evidence() {
type Counter = fn(&mut BytePoolEvidence) -> &mut EvidenceCounter;
let counters: [Counter; 17] = [
|evidence| &mut evidence.reservation_attempts,
|evidence| &mut evidence.requested_bytes,
|evidence| &mut evidence.free_extents_examined,
|evidence| &mut evidence.reservations,
|evidence| &mut evidence.exhausted_reservations,
|evidence| &mut evidence.lease_capacity_refusals,
|evidence| &mut evidence.lease_identity_refusals,
|evidence| &mut evidence.inconsistencies,
|evidence| &mut evidence.materializations,
|evidence| &mut evidence.materialized_bytes,
|evidence| &mut evidence.resume_attempts,
|evidence| &mut evidence.resumed_leases,
|evidence| &mut evidence.resume_refusals,
|evidence| &mut evidence.recycle_attempts,
|evidence| &mut evidence.recycled_leases,
|evidence| &mut evidence.recycle_refusals,
|evidence| &mut evidence.released_leases_collected,
];
for counter in counters {
let mut evidence = BytePoolEvidence::new();
assert!(evidence.valid());
counter(&mut evidence).record(u64::MAX);
assert!(evidence.valid());
counter(&mut evidence).record(1);
assert!(!evidence.valid());
}
let mut evidence = BytePoolEvidence::starting_with_active_leases(u64::MAX);
assert!(evidence.valid());
evidence.record_materialization(1);
assert!(!evidence.valid());
assert!(evidence.active_leases().invalid());
}
}