MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / dichotomy_changelist

Method dichotomy_changelist

atomic-remote/src/sync.rs:491–595  ·  view source on GitHub ↗

Find the divergence point between our cached view and the remote's actual state using binary search on Merkle states. Returns the sequence number at which divergence begins. All entries before this point are identical between cache and remote. # Algorithm 1. Check if the last cached state matches the remote's current state. If yes, we're already in sync — return `last + 1`. 2. Otherwise, binar

(&mut self, view: &str)

Source from the content-addressed store, hash-verified

489 /// Each round-trip is a single `GET ?view={s}&state=` request that
490 /// returns three values: `(position, merkle, tag_merkle)`.
491 async fn dichotomy_changelist(&mut self, view: &str) -> RemoteResult<u64> {
492 // If cache is empty, divergence is at the beginning
493 let last_seq = match self.cache.last_sequence() {
494 Some(seq) => seq,
495 None => {
496 debug!("dichotomy: cache is empty, starting from 0");
497 return Ok(0);
498 }
499 };
500
501 let last_state = match self.cache.last_merkle_state() {
502 Some(s) => s.to_string(),
503 None => return Ok(0),
504 };
505
506 debug!(
507 "dichotomy: cache has {} entries, last_seq={}, last_state={}",
508 self.cache.len(),
509 last_seq,
510 &last_state[..8.min(last_state.len())]
511 );
512
513 // Check if we're already in sync by comparing the last state
514 let remote_state = self.remote.get_state(view).await?;
515 self.stats.dichotomy_comparisons += 1;
516
517 match &remote_state {
518 StateResponse::State { merkle, .. } if *merkle == last_state => {
519 debug!("dichotomy: already in sync at seq {}", last_seq);
520 return Ok(last_seq + 1);
521 }
522 StateResponse::Empty => {
523 debug!("dichotomy: remote view is empty");
524 return Ok(0);
525 }
526 _ => {
527 debug!("dichotomy: states differ, starting binary search");
528 }
529 }
530
531 // Binary search for the divergence point
532 let mut lo: u64 = 0;
533 let mut hi: u64 = last_seq;
534
535 while lo < hi {
536 let mid = (lo + hi) / 2;
537
538 // Get the Merkle state at the midpoint from our cache
539 let cached_state = match self.cache.get_state(mid) {
540 Some(s) => s.to_string(),
541 None => {
542 // Gap in cache — we can't compare, assume divergence is here or earlier
543 debug!(
544 "dichotomy: gap in cache at {}, narrowing to [{}, {}]",
545 mid, lo, mid
546 );
547 hi = mid;
548 continue;

Callers 1

compute_deltaMethod · 0.80

Calls 6

last_sequenceMethod · 0.80
last_merkle_stateMethod · 0.80
get_changelistMethod · 0.80
get_stateMethod · 0.45
iterMethod · 0.45
as_strMethod · 0.45

Tested by

no test coverage detected