~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A profile's badges count each repository's merge batches in one query

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/profile-badges
crates/knotless-serve/src/web/badges.rs+47−28
@@ -75,11 +75,20 @@ fn badges(counts: [u64; 12]) -> Vec<BadgeView> {
pub(super) fn badges_of(index: &Index, did: &str, home: Home) -> Vec<BadgeView> {
let (shipped, stars, repos) = index.badge_counts(did).unwrap_or_default();
let mut c = Tally::default();
let mut batches = HashMap::new();
for pulls in index.pulls_by(did).unwrap_or_default() {
let items = forge::assemble(&pulls.repo, &pulls.owner, &pulls.entries);
let ejected = ejections(&pulls);
// How many each batch landed, read once the first merged pull
// names one: a query for each batch read the repository's records
// as many times over.
let mut batches = None;
for item in items.iter().filter(|i| i.author == did) {
c.authored(index, &pulls, item, &mut batches);
let ejected = ejected
.get(item.uri.as_str())
.map_or(&[][..], Vec::as_slice);
c.authored(&pulls.owner, item, ejected, || {
batches.get_or_insert_with(|| landed(index, &pulls))
});
}
}
let first = index.first_comments(did).unwrap_or_default();
@@ -126,21 +135,21 @@ struct Tally {
}
impl Tally {
/// Counts `item`, a pull the account opened on the repository of
/// `pulls`: merged into another's repository; landed by the merge
/// Counts `item`, a pull the account opened on the repository `owner`
/// keeps: merged into another's repository; landed by the merge
/// queue, never turned away, or in a batch of many; turned away for a
/// conflict and landed after all; or found by halving a batch.
/// `batches` keeps how many each batch landed, as they are counted.
fn authored(
/// `ejected` says why the runner turned it away each time, and
/// `batches` how many pulls each batch of its repository landed.
fn authored<'a>(
&mut self,
index: &Index,
pulls: &Pulls,
owner: &str,
item: &Item,
batches: &mut HashMap<String, usize>,
ejected: &[&str],
batches: impl FnOnce() -> &'a HashMap<String, usize>,
) {
let ejected = ejections(pulls, &item.uri);
let merged = item.state == "merged";
self.upstream += (merged && pulls.owner != item.author) as u64;
self.upstream += (merged && owner != item.author) as u64;
let conflicted = ejected.iter().any(|r| r.contains(CONFLICTS));
self.peacemaker += (merged && conflicted) as u64;
self.bisected += ejected.iter().any(|r| r.contains(HALVED)) as u64;
@@ -148,40 +157,50 @@ impl Tally {
return;
};
self.smooth += ejected.is_empty() as u64;
let landed = *batches
.entry(batch.clone())
.or_insert_with(|| landed(index, pulls, batch));
let landed = batches().get(batch).copied().unwrap_or_default();
self.company += (landed >= COMPANY) as u64;
}
}
/// Why the runner of the repository of `pulls` turned the pull at `uri`
/// away from its merge queue, each time it did.
fn ejections<'a>(pulls: &'a Pulls, uri: &str) -> Vec<&'a str> {
/// Why the runner of the repository of `pulls` turned each pull away from
/// its merge queue, each time it did, by the pull's URI.
fn ejections(pulls: &Pulls) -> HashMap<&str, Vec<&str>> {
let mut ejected: HashMap<&str, Vec<&str>> = HashMap::new();
let queue = pulls
.entries
.iter()
.filter(|e| e.uri.contains("/dev.knotless.queue/"));
let ejected = queue.filter(|e| {
e.value["subject"] == uri && e.value["state"] == EJECTED && pulls.repo.is_runner(&e.author)
});
for e in queue {
let turned = e.value["state"] == EJECTED && pulls.repo.is_runner(&e.author);
if let Some(subject) = e.value["subject"].as_str().filter(|_| turned) {
let reason = e.value["reason"].as_str().unwrap_or_default();
ejected.entry(subject).or_default().push(reason);
}
}
ejected
.map(|e| e.value["reason"].as_str().unwrap_or_default())
.collect()
}
/// How many pulls the merge queue landed in `batch` on the repository of
/// `pulls`, as those who may merge said.
fn landed(index: &Index, pulls: &Pulls, batch: &str) -> usize {
let states = index.batch_states(&pulls.owner, &pulls.repo.key, batch);
/// How many pulls the merge queue landed in each batch on the repository
/// of `pulls`, as those who may merge said, by the batch's tip.
fn landed(index: &Index, pulls: &Pulls) -> HashMap<String, usize> {
let states = index.batch_states(&pulls.owner, &pulls.repo.key);
let states = states.unwrap_or_default();
let merged = states.iter().filter(|e| {
let at = e.uri.rsplit('/').next().unwrap_or_default();
let by = forge::allowed(&pulls.repo, &pulls.owner, "", &e.author, "merged", at);
e.value["state"] == "merged" && by
});
let pulls: HashSet<&str> = merged.filter_map(|e| e.value["subject"].as_str()).collect();
pulls.len()
let mut batches: HashMap<&str, HashSet<&str>> = HashMap::new();
for e in merged {
if let (Some(batch), Some(pull)) = (e.value["batch"].as_str(), e.value["subject"].as_str())
{
batches.entry(batch).or_default().insert(pull);
}
}
let counted = batches
.into_iter()
.map(|(b, pulls)| (b.to_string(), pulls.len()));
counted.collect()
}
/// Whether `did` first commented on `item`, at `first`, before it merged:
crates/knotless-serve/src/index.rs+8−12
@@ -1696,22 +1696,18 @@ impl Index {
.collect())
}
/// The `merged` states naming `batch` as the tip of the merge queue's
/// batch they landed in, on the repository `owner` keeps at `key`.
pub fn batch_states(
&self,
owner: &str,
key: &str,
batch: &str,
) -> rusqlite::Result<Vec<Entry>> {
/// The states naming a batch of the merge queue, by its tip, as the
/// one they landed in, on the repository `owner` keeps at `key`.
pub fn batch_states(&self, owner: &str, key: &str) -> rusqlite::Result<Vec<Entry>> {
let db = self.readers.take(&self.db);
let mut stmt = db.prepare_cached(
"SELECT uri, author, value FROM forge
WHERE json_extract(value, '$.batch') = ?3
AND repo_did = ?1 AND repo_key = ?2
AND instr(uri, '/dev.knotless.state/') AND uri NOT IN down",
WHERE repo_did = ?1 AND repo_key = ?2
AND instr(uri, '/dev.knotless.state/')
AND json_extract(value, '$.batch') IS NOT NULL
AND uri NOT IN down",
)?;
stmt.query_map([owner, key, batch], entry)?.collect()
stmt.query_map([owner, key], entry)?.collect()
}
/// What was last found of where `did`'s account lives, and when, in