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

Method retain_view_changes

atomic-repository/src/repository/history.rs:515–599  ·  view source on GitHub ↗

Converge a view's own change log to a target effective set by removing** every own change absent from `target`. This is the removal half of set-based view convergence (the add half is [`insert_change`](crate::Repository::insert_change)). A durable view record declares the view's effective change set (its own changes plus everything inherited through its parent chain); any of the view's OWN change

(
        &self,
        view_name: &str,
        target: &HashSet<Hash>,
    )

Source from the content-addressed store, hash-verified

513 /// Idempotent: a view already matching its target removes nothing and
514 /// returns an empty vector. On success returns the hashes removed.
515 pub fn retain_view_changes(
516 &self,
517 view_name: &str,
518 target: &HashSet<Hash>,
519 ) -> Result<Vec<Hash>, RepositoryError> {
520 let mut txn = self
521 .pristine
522 .write_txn()
523 .map_err(|e| RepositoryError::Database(e.to_string()))?;
524
525 let mut view = txn
526 .get_view(view_name)
527 .map_err(|e| RepositoryError::Database(e.to_string()))?
528 .ok_or_else(|| RepositoryError::ViewNotFound {
529 name: view_name.to_string(),
530 })?;
531
532 // Snapshot the view's own change ids first (the iterator borrows the
533 // txn immutably; collecting frees it for the mutable `del_change`).
534 let own_ids: Vec<NodeId> = txn
535 .iter_changes(&view, 0)
536 .map_err(|e| RepositoryError::Database(e.to_string()))?
537 .map(|entry| entry.map(|(_seq, change_id, _merkle)| change_id))
538 .collect::<Result<_, _>>()
539 .map_err(|e| RepositoryError::Database(e.to_string()))?;
540
541 // Any own change whose external hash is not in the target set is stale.
542 let mut to_remove: Vec<(NodeId, Hash)> = Vec::new();
543 for change_id in own_ids {
544 let hash = txn
545 .get_external(change_id)
546 .map_err(|e| RepositoryError::Database(e.to_string()))?
547 .ok_or_else(|| {
548 RepositoryError::Database(format!(
549 "change {} has no external hash",
550 change_id.0
551 ))
552 })?;
553 if !target.contains(&hash) {
554 to_remove.push((change_id, hash));
555 }
556 }
557
558 if to_remove.is_empty() {
559 // Leave the write txn unwritten — nothing to converge.
560 return Ok(Vec::new());
561 }
562
563 // `del_change` re-derives the sequence from `change_id` on each call, so
564 // it is robust to the resequencing it performs internally; removal order
565 // does not affect the final set.
566 let mut removed = Vec::with_capacity(to_remove.len());
567 for (change_id, hash) in &to_remove {
568 let seq = txn
569 .del_change(&mut view, *change_id, hash)
570 .map_err(|e| RepositoryError::Database(e.to_string()))?;
571 if seq.is_some() {
572 removed.push(*hash);

Calls 15

write_txnMethod · 0.80
del_changeMethod · 0.80
update_viewMethod · 0.80
commitMethod · 0.80
get_viewMethod · 0.45
iter_changesMethod · 0.45
get_externalMethod · 0.45
containsMethod · 0.45
pushMethod · 0.45
is_emptyMethod · 0.45
lenMethod · 0.45
load_changeMethod · 0.45