diff options
| author | tv <tv@krebsco.de> | 2026-11-08 19:48:45 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-08 20:49:06 +0100 |
| commit | b40d3f7ca3f92373eca8dd0683d37183559c78e6 (patch) | |
| tree | 33431b749f234ed3bf1fdede1a4a5302464d0caf /src/access | |
| parent | 447ba15b16d71fe4c2285c4337aa99fe7b5d9df6 (diff) | |
document: tell whether a document holds a change without building it
With the policy's reads kept, judging a change still costs about one
read (some 3.5 µs), and so does judging without a policy: what is left
is At::new, which asks get_change_by_hash for each head. Automerge
builds the change again from the document's operations to answer, at
a cost growing with its history. Screening asks it again for every
candidate and every dependency, and sync for heads.
Ask by the missing dependencies instead (changes::holds), which look
the hash up: one the document holds is not among them. A change queued
in the document, waiting for its dependencies, isn't either; but then
some are missing, and only then is it asked the slow way. Every check
of whether a document holds a change goes through it.
Diffstat (limited to 'src/access')
| -rw-r--r-- | src/access/rules.rs | 2 | ||||
| -rw-r--r-- | src/access/screen.rs | 6 |
2 files changed, 4 insertions, 4 deletions
diff --git a/src/access/rules.rs b/src/access/rules.rs index 3aba0ba..bef9a13 100644 --- a/src/access/rules.rs +++ b/src/access/rules.rs @@ -125,7 +125,7 @@ pub(crate) fn judge_reading( // The first epoch's: the first change a document holds, as it comes to an empty // one, or as it is in one (judged again, `swarm::refusals`). let root = if epoch.generation == 0 { - doc.get_heads().is_empty() || doc.get_change_by_hash(&change.hash).is_some() + doc.get_heads().is_empty() || crate::document::changes::holds(doc, &change.hash) } else { change.hash.0 == epoch.id }; diff --git a/src/access/screen.rs b/src/access/screen.rs index 1c6c8c7..793e8bb 100644 --- a/src/access/screen.rs +++ b/src/access/screen.rs @@ -40,7 +40,7 @@ use crate::document::inspect::{Action, Inspector, Op, Path}; use crate::document::meta; use crate::document::replica::{Epoch, user_of}; use crate::document::signatures::Signatures; -use crate::document::{Change, ChangeHash, Document, ReadDoc}; +use crate::document::{Change, ChangeHash, Document}; /// Changes waiting for their dependencies, kept at most: the oldest go. const MAX_WAITING: usize = 10_000; @@ -289,7 +289,7 @@ pub(crate) fn apply( .into_iter() .chain(received) .filter(|change| seen.insert(change.hash())) - .filter(|change| doc.get_change_by_hash(&change.hash()).is_none()) + .filter(|change| !crate::document::changes::holds(doc, &change.hash())) .filter(|change| match refusals.root(&change.hash()) { Some(root) => { screened.refused_again += 1; @@ -780,7 +780,7 @@ fn in_order(doc: &Document, candidates: Vec<Change>) -> (Vec<Change>, Vec<Change if by_hash.contains_key(dep) { among += 1; building.entry(*dep).or_default().push(*hash); - } else if doc.get_change_by_hash(dep).is_none() { + } else if !crate::document::changes::holds(doc, dep) { missing = true; } } |
