forge_workspace/store/
bench_results.rs1use redb::{ReadableTable, TableDefinition};
10
11use crate::bench::BenchResult;
12
13use super::Db;
14
15const RESULTS: TableDefinition<&str, &[u8]> = TableDefinition::new("bench_results");
17
18pub fn key(result: &BenchResult) -> String {
20 key_parts(result.target.role, &result.target.file, result.tier, &result.corpus.sha256)
21}
22
23pub fn key_parts(
26 role: crate::bench::BenchRole,
27 file: &str,
28 tier: forge_dictate::bench::Tier,
29 corpus: &str,
30) -> String {
31 format!("{role:?}|{file}|{tier:?}|{corpus}")
32}
33
34pub fn results(db: &Db) -> anyhow::Result<Vec<BenchResult>> {
36 let txn = db.database().begin_read()?;
37 let table = match txn.open_table(RESULTS) {
38 Ok(table) => table,
39 Err(redb::TableError::TableDoesNotExist(_)) => return Ok(Vec::new()),
40 Err(error) => return Err(error.into()),
41 };
42 let mut rows = Vec::new();
43 for entry in table.iter()? {
44 let (_, value) = entry?;
45 rows.push(serde_json::from_slice(value.value())?);
46 }
47 rows.sort_by(|a: &BenchResult, b: &BenchResult| b.at.cmp(&a.at));
48 Ok(rows)
49}
50
51pub fn remove(db: &Db, key: &str) -> anyhow::Result<()> {
54 let txn = db.database().begin_write()?;
55 {
56 let mut table = match txn.open_table(RESULTS) {
57 Ok(table) => table,
58 Err(redb::TableError::TableDoesNotExist(_)) => return Ok(()),
59 Err(error) => return Err(error.into()),
60 };
61 table.remove(key)?;
62 }
63 txn.commit()?;
64 Ok(())
65}
66
67pub fn save(db: &Db, result: &BenchResult) -> anyhow::Result<()> {
70 let txn = db.database().begin_write()?;
71 {
72 let mut table = txn.open_table(RESULTS)?;
73 table.insert(key(result).as_str(), serde_json::to_vec(result)?.as_slice())?;
74 }
75 txn.commit()?;
76 Ok(())
77}