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

Method dichotomy_changelist

atomic-remote/src/sync.rs:512–616  ·  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

510 /// Each round-trip is a single `GET ?view={s}&state=` request that
511 /// returns three values: `(position, merkle, tag_merkle)`.
512 async fn dichotomy_changelist(&mut self, view: &str) -> RemoteResult<u64> {
513 // If cache is empty, divergence is at the beginning
514 let last_seq = match self.cache.last_sequence() {
515 Some(seq) => seq,
516 None => {
517 debug!("dichotomy: cache is empty, starting from 0");
518 return Ok(0);
519 }
520 };
521
522 let last_state = match self.cache.last_merkle_state() {
523 Some(s) => s.to_string(),
524 None => return Ok(0),
525 };
526
527 debug!(
528 "dichotomy: cache has {} entries, last_seq={}, last_state={}",
529 self.cache.len(),
530 last_seq,
531 &last_state[..8.min(last_state.len())]
532 );
533
534 // Check if we're already in sync by comparing the last state
535 let remote_state = self.remote.get_state(view).await?;
536 self.stats.dichotomy_comparisons += 1;
537
538 match &remote_state {
539 StateResponse::State { merkle, .. } if *merkle == last_state => {
540 debug!("dichotomy: already in sync at seq {}", last_seq);
541 return Ok(last_seq + 1);
542 }
543 StateResponse::Empty => {
544 debug!("dichotomy: remote view is empty");
545 return Ok(0);
546 }
547 _ => {
548 debug!("dichotomy: states differ, starting binary search");
549 }
550 }
551
552 // Binary search for the divergence point
553 let mut lo: u64 = 0;
554 let mut hi: u64 = last_seq;
555
556 while lo < hi {
557 let mid = (lo + hi) / 2;
558
559 // Get the Merkle state at the midpoint from our cache
560 let cached_state = match self.cache.get_state(mid) {
561 Some(s) => s.to_string(),
562 None => {
563 // Gap in cache — we can't compare, assume divergence is here or earlier
564 debug!(
565 "dichotomy: gap in cache at {}, narrowing to [{}, {}]",
566 mid, lo, mid
567 );
568 hi = mid;
569 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