use super::*;
use crate::util::statistics::stats::{SharedStats, MAX_PHASES};
use std::sync::Arc;
pub struct EventCounter {
name: String,
pub implicitly_start: bool,
merge_phases: bool,
count: Box<[u64; MAX_PHASES]>,
current_count: u64,
running: bool,
stats: Arc<SharedStats>,
}
impl EventCounter {
pub fn new(
name: String,
stats: Arc<SharedStats>,
implicitly_start: bool,
merge_phases: bool,
) -> Self {
EventCounter {
name,
implicitly_start,
merge_phases,
count: Box::new([0; MAX_PHASES]),
current_count: 0,
running: false,
stats,
}
}
pub fn inc(&mut self) {
if self.running {
self.inc_by(1);
}
}
pub fn inc_by(&mut self, value: u64) {
if self.running {
self.current_count += value;
}
}
pub fn print_current(&self) {
self.print_value(self.current_count);
}
fn print_value(&self, value: u64) {
print!("{}", value);
}
}
impl Counter for EventCounter {
fn start(&mut self) {
if !self.stats.get_gathering_stats() {
return;
}
debug_assert!(!self.running);
self.current_count = 0;
self.running = true;
}
fn stop(&mut self) {
if !self.stats.get_gathering_stats() {
return;
}
debug_assert!(self.running);
self.count[self.stats.get_phase()] = self.current_count;
self.running = false;
}
fn phase_change(&mut self, old_phase: usize) {
if self.running {
self.count[old_phase] = self.current_count;
self.current_count = 0;
}
}
fn print_count(&self, phase: usize) {
if self.merge_phases() {
debug_assert!((phase | 1) == (phase + 1));
self.print_value(self.count[phase] + self.count[phase + 1]);
} else {
self.print_value(self.count[phase]);
}
}
fn get_total(&self, other: Option<bool>) -> u64 {
match other {
None => {
let mut total = 0;
for p in 0..=self.stats.get_phase() {
total += self.count[p];
}
total
}
Some(m) => {
let mut total = 0;
let mut p = !m as usize;
while p <= self.stats.get_phase() {
total += self.count[p];
p += 2;
}
total
}
}
}
fn print_total(&self, other: Option<bool>) {
self.print_value(self.get_total(other));
}
fn print_min(&self, other: bool) {
let mut p = !other as usize;
let mut min = self.count[p];
while p < self.stats.get_phase() {
if self.count[p] < min {
min = self.count[p];
p += 2;
}
}
self.print_value(min);
}
fn print_max(&self, other: bool) {
let mut p = !other as usize;
let mut max = self.count[p];
while p < self.stats.get_phase() {
if self.count[p] > max {
max = self.count[p];
p += 2;
}
}
self.print_value(max);
}
fn print_last(&self) {
let phase = self.stats.get_phase();
if phase > 0 {
self.print_count(phase - 1);
}
}
fn merge_phases(&self) -> bool {
self.merge_phases
}
fn implicitly_start(&self) -> bool {
self.implicitly_start
}
fn name(&self) -> &String {
&self.name
}
}