diff options
| author | tv <tv@krebsco.de> | 2026-10-24 20:28:36 +0200 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-24 20:28:36 +0200 |
| commit | 59c1511bcacedddc354e82033d523f459c6db5d4 (patch) | |
| tree | fae84e91e1c7f4a98b2e99c79602ace059c6e211 /src/document | |
| parent | 8e8aee67ef8dfa7c30a3734a4b6f5357c87f1a67 (diff) | |
cache heads
To reduce the number of write locks, heads are now cached.
Diffstat (limited to 'src/document')
| -rw-r--r-- | src/document/replica.rs | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/document/replica.rs b/src/document/replica.rs index af807ea..e24f93c 100644 --- a/src/document/replica.rs +++ b/src/document/replica.rs @@ -9,7 +9,7 @@ use std::fmt; use std::ops::{Deref, DerefMut}; -use automerge::AutoCommit; +use automerge::{AutoCommit, ChangeHash}; /// One generation of the swarm document. /// @@ -77,14 +77,39 @@ impl fmt::Debug for Epoch { /// /// Derefs to the document, so code that only needs the `AutoCommit` keeps working /// with a guard of `Replica`. +/// +/// The heads are cached: `AutoCommit::get_heads` takes `&mut self` (it closes a pending +/// transaction), so without the cache every keepalive and status read would need the +/// write lock. Every path that changes the document under the write lock calls +/// [`Replica::refresh_heads`] before releasing it (`AppState::write_doc`, `mutate_doc`, +/// `switch_epoch`, the sync apply); readers take the read lock and use +/// [`Replica::heads`]. pub struct Replica { pub epoch: Epoch, pub doc: AutoCommit, + heads: Vec<ChangeHash>, } impl Replica { pub fn new(epoch: Epoch, doc: AutoCommit) -> Self { - Self { epoch, doc } + let mut replica = Self { + epoch, + doc, + heads: Vec::new(), + }; + replica.refresh_heads(); + replica + } + + /// The document's heads as of the last refresh, sorted. + pub fn heads(&self) -> &[ChangeHash] { + &self.heads + } + + /// Call after changing the document (under the write lock). + pub fn refresh_heads(&mut self) { + self.heads = self.doc.get_heads(); + self.heads.sort_unstable(); } } |
