git_perf/
measurement_retrieval.rs1use crate::{
2 data::{Commit, CommitSummary, MeasurementData, MeasurementSummary},
3 git::git_interop::{self},
4 stats::{NumericReductionFunc, ReductionFunc},
5};
6
7use anyhow::Result;
8
9pub trait MeasurementReducer<'a>: Iterator<Item = &'a MeasurementData> {
10 fn reduce_by(self, fun: ReductionFunc) -> Option<MeasurementSummary>;
11}
12
13pub fn summarize_measurements<'a, F>(
14 commits: impl Iterator<Item = Result<Commit>> + 'a,
15 summarize_by: &'a ReductionFunc,
16 filter_by: &'a F,
17) -> impl Iterator<Item = Result<CommitSummary>> + 'a
18where
19 F: Fn(&MeasurementData) -> bool,
20{
21 commits.map(move |c| {
22 c.map(|c| {
23 let measurement = c
24 .measurements
25 .iter()
26 .filter(|m| filter_by(m))
27 .reduce_by(*summarize_by);
28
29 CommitSummary {
30 commit: c.commit,
31 measurement,
32 }
33 })
34 })
35}
36
37pub fn take_while_same_epoch<I>(iter: I) -> impl Iterator<Item = Result<CommitSummary>>
39where
40 I: Iterator<Item = Result<CommitSummary>>,
41{
42 let mut first_epoch: Option<u32> = None;
43 iter.take_while(move |m| match m {
44 Ok(CommitSummary {
45 measurement: Some(m),
46 ..
47 }) => {
48 let prev_epoch = first_epoch;
49 first_epoch = Some(m.epoch);
50 prev_epoch.unwrap_or(m.epoch) == m.epoch
51 }
52 _ => true,
53 })
54}
55
56impl<'a, T> MeasurementReducer<'a> for T
57where
58 T: Iterator<Item = &'a MeasurementData>,
59{
60 fn reduce_by(self, fun: ReductionFunc) -> Option<MeasurementSummary> {
61 let mut peekable = self.peekable();
62 let expected_epoch = peekable.peek().map(|m| m.epoch);
63 let mut vals = peekable.map(|m| {
64 debug_assert_eq!(Some(m.epoch), expected_epoch);
65 m.val
66 });
67
68 let aggregate_val = vals.aggregate_by(fun);
69
70 Some(MeasurementSummary {
71 epoch: expected_epoch?,
72 val: aggregate_val?,
73 })
74 }
75}
76
77pub fn walk_commits(num_commits: usize) -> Result<impl Iterator<Item = Result<Commit>>> {
80 let vec = git_interop::walk_commits(num_commits)?;
81 Ok(vec
82 .into_iter()
83 .take(num_commits)
84 .map(|(commit_id, lines)| -> Result<Commit> {
85 let measurements = crate::serialization::deserialize(&lines.join("\n"));
86 Ok(Commit {
87 commit: commit_id,
88 measurements,
89 })
90 }))
91 }