aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/screen.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-08 20:30:45 +0000
committertv <tv@krebsco.de>2026-11-08 21:33:06 +0100
commit51da8017d4592b31e904f505cab18ae1854df08b (patch)
tree0dd2b51e5fbed00a10c8e929f162496934dc3d46 /src/access/screen.rs
parent54399ae3528deeeba5b09fc619394d2f2cd287f9 (diff)
screen: share the heads a change is judged at with what it builds on
Each change taken but not yet applied got its own set of the heads it is judged at, built in an ordered set and copied into a vector, and kept so for those building on it. Most build on one change alone and are judged at its heads: share them instead (reference counted), and build a set only for a change with several dependencies.
Diffstat (limited to 'src/access/screen.rs')
-rw-r--r--src/access/screen.rs28
1 files changed, 19 insertions, 9 deletions
diff --git a/src/access/screen.rs b/src/access/screen.rs
index 68e4db7..3a516e3 100644
--- a/src/access/screen.rs
+++ b/src/access/screen.rs
@@ -375,7 +375,7 @@ pub(crate) fn apply(
}
// The changes of the document each accepted one, not applied yet, builds on.
- let mut frontier: HashMap<ChangeHash, Vec<ChangeHash>> = HashMap::new();
+ let mut frontier: HashMap<ChangeHash, std::rc::Rc<[ChangeHash]>> = HashMap::new();
// Refused in this batch, each with the change that broke a rule.
let mut refused: HashMap<ChangeHash, ChangeHash> = HashMap::new();
let mut unsigned: HashSet<ChangeHash> = HashSet::new();
@@ -458,16 +458,26 @@ pub(crate) fn apply(
unapplied.clear();
signed = None;
}
- let mut seen_at: BTreeSet<ChangeHash> = BTreeSet::new();
- for dep in change.deps() {
- match frontier.get(dep) {
- Some(heads) => seen_at.extend(heads.iter().copied()),
- None => {
- seen_at.insert(*dep);
+ // Shared with what it builds on, if it builds on one alone (most do): the same
+ // heads, not a copy each.
+ let seen_at: std::rc::Rc<[ChangeHash]> = match change.deps() {
+ [dep] => frontier
+ .get(dep)
+ .cloned()
+ .unwrap_or_else(|| std::rc::Rc::from([*dep])),
+ deps => {
+ let mut seen_at: BTreeSet<ChangeHash> = BTreeSet::new();
+ for dep in deps {
+ match frontier.get(dep) {
+ Some(heads) => seen_at.extend(heads.iter().copied()),
+ None => {
+ seen_at.insert(*dep);
+ }
+ }
}
+ seen_at.into_iter().collect()
}
- }
- let seen_at: Vec<ChangeHash> = seen_at.into_iter().collect();
+ };
let root = change.deps().is_empty();
let judged = if judging || root {
rules::judge_reading(