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

Function write_change_to_graph

atomic-repository/src/apply/mod.rs:229–385  ·  view source on GitHub ↗

Write a change to the graph and add it to a view's change log. This function handles two cases: 1. **New change**: The change hasn't been applied to the graph yet. We apply all hunks and add it to the view's change log. 2. **Existing change**: The change is already in the graph (applied via another view). We skip hunk application and just add it to the view's change log. This distinction is cruc

(
    txn: &mut WriteTxn<'_>,
    view_name: &str,
    change_id: NodeId,
    change_hash: &Hash,
    change: &Change,
    options: &InsertOptions,
    already_in_graph: bool,
)

Source from the content-addressed store, hash-verified

227///
228/// The result of the insertion including new state and conflict info.
229pub fn write_change_to_graph(
230 txn: &mut WriteTxn<'_>,
231 view_name: &str,
232 change_id: NodeId,
233 change_hash: &Hash,
234 change: &Change,
235 options: &InsertOptions,
236 already_in_graph: bool,
237) -> InsertResult<InsertOutcome> {
238 let mut workspace = Workspace::new();
239 let mut conflict_tracker = ConflictTracker::new();
240 let mut stats = InsertStats::new();
241 let trace_record = std::env::var_os("ATOMIC_TRACE_RECORD").is_some()
242 || std::env::var_os("ATOMIC_TRACE_INSERT").is_some();
243
244 // Get the current view
245 let mut view = txn
246 .open_or_create_view(view_name)
247 .map_err(|e| InsertError::Database(e.to_string()))?;
248
249 // Validate we can apply (unless caller explicitly skipped validation,
250 // e.g. rebuild_change_graph re-applying an existing change with new hunks).
251 if !options.skip_validation {
252 validate_can_apply(txn, &view, change_id, change_hash, change)?;
253 }
254
255 // Only apply hunks if the change isn't already in the graph.
256 // All edges go to the global GRAPH + INODE_GRAPH tables.
257 let should_apply_hunks = !already_in_graph;
258
259 log::debug!(
260 "write_change_to_graph: change_id={:?} hash={} should_apply_hunks={} view_kind={:?}",
261 change_id,
262 change_hash.to_base32(),
263 should_apply_hunks,
264 view.kind
265 );
266
267 if should_apply_hunks {
268 let hunks = change.hunks();
269 let total_hunks = hunks.len();
270 let hunk_phase_start = std::time::Instant::now();
271 // Open GRAPH + INODE_GRAPH once for the whole hunk pass. All graph
272 // reads and writes flow through this cached handle, so the tables are
273 // opened twice per change instead of ~6 times per hunk. The scope ends
274 // before the FileOps/view-update phase, which needs `&mut txn` again.
275 {
276 let mut cached = CachedWriteGraphTxn::new(&*txn)
277 .map_err(|e| InsertError::Database(e.to_string()))?;
278 for (hunk_idx, graph_op) in hunks.iter().enumerate() {
279 if trace_record && (hunk_idx == 0 || (hunk_idx + 1) % 1_000 == 0) {
280 eprintln!(
281 "[write_change_to_graph] applying hunk {}/{} elapsed={:?}",
282 hunk_idx + 1,
283 total_hunks,
284 hunk_phase_start.elapsed()
285 );
286 }

Callers 4

write_import_recordedMethod · 0.85
insert_changeMethod · 0.85
write_recordedMethod · 0.85

Calls 15

validate_can_applyFunction · 0.85
write_hunkFunction · 0.85
apply_file_ops_batchedFunction · 0.85
compute_new_stateFunction · 0.85
open_or_create_viewMethod · 0.80
put_changeMethod · 0.80
update_viewMethod · 0.80
total_conflict_countMethod · 0.80
hunksMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
has_file_opsMethod · 0.45

Tested by

no test coverage detected