aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/screen.rs
diff options
context:
space:
mode:
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(