aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/document/signatures.rs27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/document/signatures.rs b/src/document/signatures.rs
index 8577619..4554420 100644
--- a/src/document/signatures.rs
+++ b/src/document/signatures.rs
@@ -210,6 +210,9 @@ struct Pending {
by_change: HashMap<ChangeHash, [u8; 64]>,
/// The changes, oldest first; some may have left `by_change` since.
order: std::collections::VecDeque<ChangeHash>,
+ /// The document's heads when `offer` last looked for those whose changes came: as
+ /// long as they stand, none came (`arrived`).
+ scanned: Vec<ChangeHash>,
}
impl Pending {
@@ -235,8 +238,19 @@ impl Pending {
self.by_change.remove(hash)
}
- fn keys(&self) -> impl Iterator<Item = &ChangeHash> {
- self.by_change.keys()
+ /// Those whose changes `doc` holds now: none where its heads are those of the last
+ /// look, as a document only grows; else each looked up.
+ fn arrived(&mut self, doc: &Document) -> Vec<ChangeHash> {
+ let heads = doc.get_heads();
+ if heads == self.scanned {
+ return Vec::new();
+ }
+ self.scanned = heads;
+ self.by_change
+ .keys()
+ .filter(|hash| super::changes::holds(doc, hash))
+ .copied()
+ .collect()
}
}
@@ -376,12 +390,7 @@ impl Signatures {
Vouched::Nothing => {}
}
}
- let arrived: Vec<ChangeHash> = self
- .pending
- .keys()
- .filter(|hash| super::changes::holds(doc, hash))
- .copied()
- .collect();
+ let arrived = self.pending.arrived(doc);
// Their own budget: what waited came from any peer, not only this one.
let mut invalid_waiting = 0;
for hash in arrived {
@@ -890,7 +899,7 @@ mod tests {
for i in 0..=MAX_PENDING {
pending.insert(hash(i), [0; 64]);
}
- assert_eq!(pending.keys().count(), MAX_PENDING);
+ assert_eq!(pending.by_change.len(), MAX_PENDING);
assert!(pending.remove(&hash(0)).is_none());
assert!(pending.remove(&hash(MAX_PENDING)).is_some());
}