From 51da8017d4592b31e904f505cab18ae1854df08b Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 20:30:45 +0000 Subject: 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. --- src/access/screen.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/access/screen.rs') 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> = HashMap::new(); + let mut frontier: HashMap> = HashMap::new(); // Refused in this batch, each with the change that broke a rule. let mut refused: HashMap = HashMap::new(); let mut unsigned: HashSet = HashSet::new(); @@ -458,16 +458,26 @@ pub(crate) fn apply( unapplied.clear(); signed = None; } - let mut seen_at: BTreeSet = 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 = 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 = seen_at.into_iter().collect(); + }; let root = change.deps().is_empty(); let judged = if judging || root { rules::judge_reading( -- cgit v1.3.1