use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, Default)]
pub struct Progress {
pub sequences_processed: u64,
pub bases_processed: u64,
}
#[derive(Debug, Default)]
pub struct ProgressTracker {
sequences: AtomicU64,
bases: AtomicU64,
}
impl ProgressTracker {
#[must_use]
pub const fn new() -> Self {
Self {
sequences: AtomicU64::new(0),
bases: AtomicU64::new(0),
}
}
pub fn record_sequence(&self, bases: u64) {
self.sequences.fetch_add(1, Ordering::Relaxed);
self.bases.fetch_add(bases, Ordering::Relaxed);
}
pub fn snapshot(&self) -> Progress {
Progress {
sequences_processed: self.sequences.load(Ordering::Relaxed),
bases_processed: self.bases.load(Ordering::Relaxed),
}
}
pub fn reset(&self) {
self.sequences.store(0, Ordering::Relaxed);
self.bases.store(0, Ordering::Relaxed);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tracker_starts_at_zero() {
let tracker = ProgressTracker::new();
let progress = tracker.snapshot();
assert_eq!(progress.sequences_processed, 0);
assert_eq!(progress.bases_processed, 0);
}
#[test]
fn tracker_records_sequence() {
let tracker = ProgressTracker::new();
tracker.record_sequence(100);
tracker.record_sequence(50);
let progress = tracker.snapshot();
assert_eq!(progress.sequences_processed, 2);
assert_eq!(progress.bases_processed, 150);
}
#[test]
fn tracker_reset() {
let tracker = ProgressTracker::new();
tracker.record_sequence(100);
tracker.reset();
let progress = tracker.snapshot();
assert_eq!(progress.sequences_processed, 0);
assert_eq!(progress.bases_processed, 0);
}
}