From 0d16147e95211b0829fddaefb0d014fe0c48dbc8 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 5 Nov 2026 00:57:05 +0100 Subject: new changes per message --- src/document/sync.rs | 8 +++++--- src/simtest/bench.rs | 15 +++++++++++++++ src/swarm/stats.rs | 8 ++++++++ src/swarm/sync.rs | 3 ++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/document/sync.rs b/src/document/sync.rs index 0aeec83..1f61f70 100644 --- a/src/document/sync.rs +++ b/src/document/sync.rs @@ -427,17 +427,19 @@ impl SyncSession { /// the peer's own changes back. A delta comes outside the sync protocol, so /// Automerge would think the peer lacks all of it, and offer it back as a delta of /// our own. Counted as sent (`sent_hashes`), they don't; Automerge forgets them as - /// sent once the peer's heads cover them. (Changes kept until their predecessors came, + /// sent once the peer's heads cover them. Returns how many changes that is. (Changes kept until their predecessors came, /// from another peer, count too: should this one lack them, it asks, and gets them, /// `resend_if_needed`.) pub(crate) fn came_from_peer( &mut self, doc: &Document, before: &[crate::document::ChangeHash], - ) { - for change in doc.get_changes_meta(before) { + ) -> usize { + let changes = doc.get_changes_meta(before); + for change in &changes { self.state.sent_hashes.insert(change.hash); } + changes.len() } /// Of the changes in `doc` beyond `from`, how many the peer has too, as far as we diff --git a/src/simtest/bench.rs b/src/simtest/bench.rs index 3b1b3e6..5242633 100644 --- a/src/simtest/bench.rs +++ b/src/simtest/bench.rs @@ -292,6 +292,7 @@ impl Totals { relay.carrying += stats.relay.carrying; relay.carrying_change_bytes += stats.relay.carrying_change_bytes; relay.carrying_bloom_bytes += stats.relay.carrying_bloom_bytes; + relay.new_changes += stats.relay.new_changes; relay.nothing_new_change_bytes += stats.relay.nothing_new_change_bytes; relay.nothing_new_bloom_bytes += stats.relay.nothing_new_bloom_bytes; relay.off_tree += stats.relay.off_tree; @@ -619,6 +620,20 @@ fn report( twice ), ); + // Bytes of changes per new change in the messages that brought some: several + // changes per message, or larger changes. + let with_news = carrying - twice; + let news = r1.new_changes - r0.new_changes; + let _ = writeln!( + out, + " of those with something new: {:.1} new changes each, {:.0} bytes of changes per new change", + each(news, with_news), + each( + (r1.carrying_change_bytes - r0.carrying_change_bytes) + - (r1.nothing_new_change_bytes - r0.nothing_new_change_bytes), + news + ), + ); let (i0, i1) = (during.0.incidents, during.1.incidents); let _ = writeln!( out, diff --git a/src/swarm/stats.rs b/src/swarm/stats.rs index c322305..b51a802 100644 --- a/src/swarm/stats.rs +++ b/src/swarm/stats.rs @@ -143,6 +143,9 @@ pub(crate) struct Relay { pub(crate) carrying_bloom_bytes: u64, pub(crate) nothing_new_change_bytes: u64, pub(crate) nothing_new_bloom_bytes: u64, + /// The changes new to us that sync messages brought (beside what they carried that + /// we had): with `carrying` less `nothing_new`, how many a message with news brings. + pub(crate) new_changes: u64, /// Changes from elsewhere that came not along a writer's tree (pulled, with an /// answer, sent again, fetched as a delta), and their delays summed (as `Propagation`). pub(crate) off_tree: u64, @@ -282,6 +285,11 @@ impl NodeStats { inner.relay.carrying_bloom_bytes += sizes.1 as u64; } + /// A sync message brought `count` changes new to us. + pub(crate) fn new_changes(&self, count: usize) { + self.lock().relay.new_changes += count as u64; + } + /// A sync message of `bytes` arrived. pub(crate) fn sync_received(&self, bytes: usize) { let mut inner = self.lock(); diff --git a/src/swarm/sync.rs b/src/swarm/sync.rs index 2a08aae..9a63c8b 100644 --- a/src/swarm/sync.rs +++ b/src/swarm/sync.rs @@ -506,7 +506,8 @@ pub(crate) async fn handle_sync( let changed = heads_after != heads_before; if changed { // They came from it: none goes back (`SyncSession::came_from_peer`). - peer_state.sync.came_from_peer(&replica.doc, &heads_before); + let new = peer_state.sync.came_from_peer(&replica.doc, &heads_before); + stats.new_changes(new); } if carried && !changed { stats.nothing_new(payload_len, writer.is_some(), delivered, sizes); -- cgit v1.3.1