Skip to content

Commit 2ef8bc7

Browse files
Ingest new commits on push
1 parent bf84e5a commit 2ef8bc7

File tree

12 files changed

+240
-192
lines changed

12 files changed

+240
-192
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ rustc-artifacts = "0.2"
3535
itertools = "0.9"
3636
hashbrown = "0.7"
3737
rocksdb = "0.14"
38+
arc-swap = "0.4"
3839

3940
[dependencies.collector]
4041
path = "../collector"

site/src/bin/ingest.rs

Lines changed: 3 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,6 @@
1-
use anyhow::Context as _;
2-
use rocksdb::WriteBatch;
3-
use std::fs;
4-
use std::io::Read as _;
51
use std::path::Path;
62

7-
use collector::{ArtifactData, CommitData};
8-
use site::db::{CollectionId, DbLabel, Label, LabelPath, LabelTag, Profile};
9-
10-
enum Res {
11-
Artifact(ArtifactData),
12-
Commit(CommitData),
13-
}
14-
15-
fn deserialize_path(path: &Path) -> Res {
16-
let mut file = fs::File::open(path)
17-
.with_context(|| format!("Failed to open {}", path.display()))
18-
.unwrap();
19-
let mut file_contents = Vec::new();
20-
if path.extension().map_or(false, |e| e == "sz") {
21-
let mut szip_reader = snap::read::FrameDecoder::new(std::io::BufReader::new(file));
22-
szip_reader
23-
.read_to_end(&mut file_contents)
24-
.with_context(|| format!("Failed to read {}", path.display()))
25-
.unwrap();
26-
} else {
27-
file.read_to_end(&mut file_contents)
28-
.with_context(|| format!("Failed to read {}", path.display()))
29-
.unwrap();
30-
};
31-
32-
if path
33-
.file_name()
34-
.unwrap()
35-
.to_str()
36-
.unwrap()
37-
.starts_with("artifact-")
38-
{
39-
Res::Artifact(serde_json::from_slice(&file_contents).unwrap())
40-
} else {
41-
Res::Commit(serde_json::from_slice(&file_contents).unwrap())
42-
}
43-
}
44-
45-
fn main() -> Result<(), Box<dyn std::error::Error>> {
3+
fn main() {
464
let dir = std::env::args().nth(1).expect("database as first arg");
475
let db = site::db::open(&dir, true);
486
let mut index = site::db::Index::load(&db);
@@ -53,90 +11,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
5311
for (idx, path) in paths.into_iter().enumerate() {
5412
if idx % 10 == 0 {
5513
eprintln!(
56-
"{}/{}, per {:?}; total {:?}",
14+
"{}/{}, per {:?}; estimated total time {:?}",
5715
idx,
5816
paths_count,
5917
last.elapsed() / 10,
6018
last.elapsed() / 10 * paths_count as u32
6119
);
6220
last = std::time::Instant::now();
6321
}
64-
let res = deserialize_path(std::path::Path::new(&path));
65-
let (cid, benchmarks) = match res {
66-
Res::Commit(cd) => (CollectionId::Commit(cd.commit), cd.benchmarks),
67-
Res::Artifact(ad) => (CollectionId::Artifact(ad.id), ad.benchmarks),
68-
};
69-
70-
let cid_num = index.intern_cid(&cid);
71-
let mut path = LabelPath::new();
72-
73-
for (name, bres) in benchmarks.into_iter() {
74-
path.set(Label::Crate(name));
75-
let benchmark = match bres {
76-
Ok(b) => b,
77-
Err(e) => {
78-
let mut batch = WriteBatch::default();
79-
index.insert_labeled(&DbLabel::Errors { krate: name }, &mut batch, cid_num, &e);
80-
db.write(batch).unwrap();
81-
path.remove(LabelTag::Crate);
82-
continue;
83-
}
84-
};
85-
86-
for run in &benchmark.runs {
87-
let mut batch = WriteBatch::default();
88-
let profile = if run.check {
89-
Profile::Check
90-
} else if run.release {
91-
Profile::Opt
92-
} else {
93-
Profile::Debug
94-
};
95-
let state = (&run.state).into();
96-
path.set(Label::Profile(profile));
97-
path.set(Label::Cache(state));
98-
99-
for (sid, stat) in run.stats.iter() {
100-
path.set(Label::ProcessStat(sid.as_pstat()));
101-
index.insert_labeled(
102-
&DbLabel::ProcessStat {
103-
krate: name,
104-
profile,
105-
cache: state,
106-
stat: sid.as_pstat(),
107-
},
108-
&mut batch,
109-
cid_num,
110-
&stat,
111-
);
112-
}
113-
path.remove(LabelTag::ProcessStat);
114-
115-
if let Some(self_profile) = &run.self_profile {
116-
for qd in self_profile.query_data.iter() {
117-
path.set(Label::Query(qd.label));
118-
index.insert_labeled(
119-
&DbLabel::SelfProfileQuery {
120-
krate: name,
121-
profile,
122-
cache: state,
123-
query: qd.label,
124-
},
125-
&mut batch,
126-
cid_num,
127-
&site::db::QueryDatum::from_query_data(qd),
128-
);
129-
}
130-
path.remove(LabelTag::Query);
131-
}
132-
db.write_without_wal(batch).unwrap();
133-
}
134-
}
22+
site::ingest::ingest(&db, &mut index, Path::new(&path));
13523
}
13624

13725
index.store(&db);
13826
db.flush().unwrap();
139-
std::mem::drop(db);
140-
141-
Ok(())
14227
}

site/src/db.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,25 @@ pub fn data_for(data: &[Commit], is_left: bool, query: Bound) -> Option<Commit>
103103
}
104104
}
105105

106-
pub fn range_subset(data: &[Commit], range: RangeInclusive<Bound>) -> &[Commit] {
106+
pub fn range_subset(data: Vec<Commit>, range: RangeInclusive<Bound>) -> Vec<Commit> {
107107
let (a, b) = range.into_inner();
108108

109109
let left_idx = data.iter().position(|commit| a.left_match(commit));
110110
let right_idx = data.iter().rposition(|commit| b.left_match(commit));
111111

112112
if let (Some(left), Some(right)) = (left_idx, right_idx) {
113-
data.get(left..=right).unwrap_or_else(|| {
114-
log::error!(
115-
"Failed to compute left/right indices from {:?}..={:?}",
116-
a,
117-
b
118-
);
119-
&[]
120-
})
113+
data.get(left..=right)
114+
.map(|s| s.to_vec())
115+
.unwrap_or_else(|| {
116+
log::error!(
117+
"Failed to compute left/right indices from {:?}..={:?}",
118+
a,
119+
b
120+
);
121+
vec![]
122+
})
121123
} else {
122-
&[]
124+
vec![]
123125
}
124126
}
125127

@@ -567,7 +569,7 @@ pub fn open(at: &str, ingest: bool) -> DB {
567569
DB::open_cf_descriptors(&db_opts, &at, descriptors).unwrap()
568570
}
569571

570-
#[derive(Deserialize, Serialize, Default)]
572+
#[derive(Clone, Deserialize, Serialize, Default)]
571573
pub struct Index {
572574
commits: Indexed<Commit>,
573575
artifacts: Indexed<Box<str>>,
@@ -577,7 +579,7 @@ pub struct Index {
577579
queries: Indexed<(Crate, Profile, Cache, QueryLabel)>,
578580
}
579581

580-
#[derive(Serialize, Deserialize)]
582+
#[derive(Clone, Serialize, Deserialize)]
581583
struct Indexed<T> {
582584
#[serde(with = "index_serde")]
583585
#[serde(bound = "T: Serialize + serde::de::DeserializeOwned + std::hash::Hash + Eq")]
@@ -753,7 +755,9 @@ impl Index {
753755
}
754756

755757
pub fn commits(&self) -> Vec<Commit> {
756-
self.commits.map.keys().copied().collect()
758+
let mut commits = self.commits.map.keys().copied().collect::<Vec<_>>();
759+
commits.sort();
760+
commits
757761
}
758762

759763
// FIXME: in theory this won't scale indefinitely as there's potentially

site/src/git.rs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,58 @@
88
// except according to those terms.
99

1010
use std::path::Path;
11+
use std::path::PathBuf;
1112
use std::process::Command;
1213

1314
use crate::CommandFailed;
1415

15-
const BRANCH: &'static str = "master";
16-
const GIT: &'static str = "git";
17-
const GIT_CHECKOUT: &'static str = "checkout";
18-
const GIT_PULL: &'static str = "pull";
19-
20-
pub fn update_repo(repo_path: &str) -> anyhow::Result<()> {
16+
pub fn update_repo(repo_path: &str) -> anyhow::Result<Vec<PathBuf>> {
2117
let working_dir = Path::new(repo_path);
22-
checkout_master(working_dir)?;
23-
pull_updates(working_dir)?;
24-
Ok(())
18+
execute_command(working_dir, &["checkout", "master"])?;
19+
let original = get_commit_hash(working_dir)?;
20+
execute_command(working_dir, &["pull"])?;
21+
22+
let output = Command::new("git")
23+
.current_dir(working_dir)
24+
.arg("diff")
25+
.arg("--name-only")
26+
.arg(&original)
27+
.output()?;
28+
if !output.status.success() {
29+
Err(CommandFailed {
30+
command: format!("git diff --name-only {}", original),
31+
})?
32+
}
33+
Ok(String::from_utf8(output.stdout)?
34+
.lines()
35+
.map(|l| PathBuf::from(repo_path).join(l.trim()))
36+
.collect())
37+
}
38+
39+
fn get_commit_hash(working_dir: &Path) -> anyhow::Result<String> {
40+
let output = Command::new("git")
41+
.current_dir(working_dir)
42+
.arg("rev-parse")
43+
.arg("master")
44+
.output()?;
45+
if !output.status.success() {
46+
Err(CommandFailed {
47+
command: format!("git rev-parse master"),
48+
})?
49+
}
50+
Ok(String::from_utf8(output.stdout)?.trim().to_string())
2551
}
2652

2753
pub fn execute_command(working_dir: &Path, args: &[&str]) -> anyhow::Result<()> {
28-
let status = Command::new(GIT)
54+
let status = Command::new("git")
2955
.current_dir(working_dir)
3056
.args(args)
3157
.status()?;
3258
if status.success() {
3359
Ok(())
3460
} else {
3561
Err(CommandFailed {
36-
command: format!("{} {:?}", GIT, args),
62+
command: format!("git {:?}", args),
3763
})?
3864
}
3965
}
40-
41-
fn checkout_master(working_dir: &Path) -> anyhow::Result<()> {
42-
execute_command(working_dir, &[GIT_CHECKOUT, BRANCH])
43-
}
44-
45-
fn pull_updates(working_dir: &Path) -> anyhow::Result<()> {
46-
execute_command(working_dir, &[GIT_PULL])
47-
}

0 commit comments

Comments
 (0)