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

Method rebuild_session_index

atomic-repository/src/repository/changes.rs:420–596  ·  view source on GitHub ↗

Rebuild session indexes from stored provenance graphs. Idempotent: existing `(session, provenance)` pairs are skipped, so a rebuilt repository never gains duplicate turns. Corrupt provenance files are reported in the result rather than aborting the rebuild. Returns `(indexed_count, skipped_existing, corrupt_count)`.

(&self)

Source from the content-addressed store, hash-verified

418 /// files are reported in the result rather than aborting the rebuild.
419 /// Returns `(indexed_count, skipped_existing, corrupt_count)`.
420 pub fn rebuild_session_index(&self) -> Result<(usize, usize, usize), RepositoryError> {
421 let mut indexed = 0usize;
422 let mut skipped = 0usize;
423 let mut corrupt = 0usize;
424
425 // Collect (hash, graph) pairs first so each write txn is short-lived.
426 let mut graphs: Vec<(Hash, atomic_core::change::ProvenanceGraph)> = Vec::new();
427 for result in self.change_store.iter_provenance_graphs() {
428 match result {
429 Ok(hash) => match self.load_provenance_graph(&hash) {
430 Ok(graph) => graphs.push((hash, graph)),
431 Err(_) => corrupt += 1,
432 },
433 Err(_) => corrupt += 1,
434 }
435 }
436
437 // Group by session. The core index derives canonical turn order from
438 // the complete set, independent of this ingestion order.
439 let mut by_session: std::collections::BTreeMap<
440 String,
441 Vec<(Hash, atomic_core::change::ProvenanceGraph)>,
442 > = std::collections::BTreeMap::new();
443 let mut head_manifests = std::collections::BTreeMap::new();
444 let mut fork_parents = std::collections::BTreeMap::new();
445 for (hash, graph) in graphs {
446 by_session
447 .entry(graph.session_id.clone())
448 .or_default()
449 .push((hash, graph));
450 }
451 // Forked children can contain only inherited turns, whose provenance
452 // files still name the parent session. Include both existing ledgers
453 // and portable manifests so rebuild can create or migrate the child.
454 {
455 let txn = self
456 .pristine
457 .read_txn()
458 .map_err(|e| RepositoryError::Database(e.to_string()))?;
459 for record in txn
460 .list_session_records()
461 .map_err(|e| RepositoryError::Database(e.to_string()))?
462 {
463 if record.turn_count > 0 {
464 by_session.entry(record.session_id).or_default();
465 }
466 }
467 for (head_session_id, head) in txn
468 .list_session_heads()
469 .map_err(|e| RepositoryError::Database(e.to_string()))?
470 {
471 match txn.get_session_manifest(&head) {
472 Ok(Some(manifest)) if manifest.session_id == head_session_id => {
473 if let (Some(parent_hash), Some(fork_turn)) =
474 (manifest.parent_session, manifest.fork_turn)
475 {
476 if let Ok(Some(parent)) = txn.get_session_manifest(&parent_hash) {
477 fork_parents.insert(

Calls 15

read_txnMethod · 0.80
list_session_recordsMethod · 0.80
list_session_headsMethod · 0.80
cmpMethod · 0.80
get_session_recordMethod · 0.80
get_session_turnsMethod · 0.80
write_txnMethod · 0.80
index_session_turnMethod · 0.80
index_inherited_turnMethod · 0.80
index_empty_sessionMethod · 0.80