use keyhog_profile::{CounterId, TypedMetricRecordV2};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Phase2VerificationProfile {
pub anchor_collect_ns: u64,
pub anchor_collect_calls: u64,
pub anchor_candidates: u64,
pub anchored_verify_candidates: u64,
pub anchored_verify_matches: u64,
pub whole_chunk_patterns: u64,
pub whole_chunk_matches: u64,
}
impl Phase2VerificationProfile {
pub fn any_recorded(&self) -> bool {
*self != Self::default()
}
}
pub fn phase2_verification_profile_from_typed(
metrics: &[TypedMetricRecordV2],
) -> Phase2VerificationProfile {
let value = |counter: CounterId| {
metrics
.iter()
.find(|record| record.metric_id == counter.metric_id())
.map_or(0, |record| record.value)
};
Phase2VerificationProfile {
anchor_collect_ns: value(CounterId::Phase2AnchorCollectNs),
anchor_collect_calls: value(CounterId::Phase2AnchorCollectCalls),
anchor_candidates: value(CounterId::Phase2AlwaysAnchorCandidateCount),
anchored_verify_candidates: value(CounterId::Phase2AnchoredVerifyCandidates),
anchored_verify_matches: value(CounterId::Phase2AnchoredVerifyMatches),
whole_chunk_patterns: value(CounterId::Phase2WholeChunkPatterns),
whole_chunk_matches: value(CounterId::Phase2WholeChunkMatches),
}
}
pub fn format_phase2_verification_profile(p: &Phase2VerificationProfile) -> String {
let ac_ms = p.anchor_collect_ns as f64 / 1e6;
format!(
"=== PHASE2 verification profile === anchor-collect={ac_ms:.1}ms (calls={} cands={}) \
anchored-verify=(cands={} matches={}) whole-chunk=(patterns={} matches={})",
p.anchor_collect_calls,
p.anchor_candidates,
p.anchored_verify_candidates,
p.anchored_verify_matches,
p.whole_chunk_patterns,
p.whole_chunk_matches,
)
}
pub(crate) fn anchor_collect_span() -> keyhog_profile::CounterSpan {
keyhog_profile::add_counter(CounterId::Phase2AnchorCollectCalls, 1);
keyhog_profile::counter_span(CounterId::Phase2AnchorCollectNs)
}
pub(crate) fn record_anchor_candidates(count: usize) {
keyhog_profile::add_counter(CounterId::Phase2AlwaysAnchorCandidateCount, count as u64);
}
pub(crate) fn record_anchored_verify_candidates(count: usize) {
keyhog_profile::add_counter(CounterId::Phase2AnchoredVerifyCandidates, count as u64);
}
pub(crate) fn record_anchored_verify_matches(before: usize, after: usize) {
if after > before {
keyhog_profile::add_counter(
CounterId::Phase2AnchoredVerifyMatches,
(after - before) as u64,
);
}
}
pub(crate) fn record_whole_chunk_pattern() {
keyhog_profile::add_counter(CounterId::Phase2WholeChunkPatterns, 1);
}
pub(crate) fn record_whole_chunk_matches(before: usize, after: usize) {
if after > before {
keyhog_profile::add_counter(CounterId::Phase2WholeChunkMatches, (after - before) as u64);
}
}