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

Function write_new_edge

atomic-core/src/apply/edge.rs:144–235  ·  view source on GitHub ↗

Write a single NewEdge operation to the graph. This handles the actual edge modification: resolving positions, removing old edges, adding new edges, and detecting zombie conflicts. Edges are written to the global GRAPH and INODE_GRAPH tables. # Arguments `txn` - Write transaction `workspace` - Workspace for tracking state `change_id` - Internal ID of current change `inode` - File inode positio

(
    txn: &mut CachedWriteGraphTxn<'_, '_>,
    workspace: &mut Workspace,
    change_id: NodeId,
    inode: &Position<Option<Hash>>,
    edge: &NewEdge<Option<Hash>>,
    change: &Change,
    detect

Source from the content-addressed store, hash-verified

142/// * `edge` - The edge to write
143/// * `change` - Full change for dependency checking
144fn write_new_edge(
145 txn: &mut CachedWriteGraphTxn<'_, '_>,
146 workspace: &mut Workspace,
147 change_id: NodeId,
148 inode: &Position<Option<Hash>>,
149 edge: &NewEdge<Option<Hash>>,
150 change: &Change,
151 detect_conflicts: bool,
152) -> Result<(), LocalApplyError> {
153 log::debug!(
154 "write_new_edge: flag={:?} from={:?} to={:?}",
155 edge.flag,
156 edge.from,
157 edge.to
158 );
159
160 // Resolve the introduced_by change for validation / side effects.
161 // The resolved id itself is unused here — the additive-only edge
162 // model writes the new edge directly without consulting it.
163 let _ = resolve_introduced_by(txn, &edge.introduced_by, change_id)?;
164
165 // Find source span — predecessor context (ending at position).
166 let source_pos = resolve_position(txn, &edge.from, change_id)?;
167 let source = resolve_vertex(txn, source_pos, true)?;
168
169 // Prefer the exact serialized target span when it already exists.
170 // Structural updates like FileMove name deletions refer to a concrete
171 // vertex span, and reducing them to start_pos loses that precision.
172 let exact_target = resolve_exact_vertex(txn, &edge.to, change_id)?;
173 let mut target = if txn
174 .has_vertex(exact_target)
175 .map_err(|e| LocalApplyError::Internal {
176 message: format!("Failed to check target vertex: {}", e),
177 })? {
178 exact_target
179 } else {
180 let target_pos = resolve_position(txn, &edge.to.start_pos(), change_id)?;
181 resolve_vertex(txn, target_pos, false)?
182 };
183
184 // Resolve inode for indexing
185 let resolved_inode = resolve_inode(txn, inode, change_id)?;
186
187 // Parse the edge kind for semantic dispatch.
188 // `edge.flag` is still `EdgeFlags` (wire format from the change), so we
189 // parse it into a typed `EdgeKind` for cleaner branching below.
190 let kind = EdgeKind::from_flags(edge.flag);
191
192 // Track folder files for conflict detection
193 if kind.is_some_and(|k| k.is_folder()) {
194 workspace.mark_rooted(target.start_pos());
195 }
196
197 // Handle potential span splitting for partial targets
198 let target_end_pos = resolve_position(txn, &edge.to.end_pos(), change_id)?;
199 if target.end > target_end_pos.pos {
200 // Target span extends beyond the edge target - adjust
201 target = GraphNode {

Callers 1

write_edge_mapFunction · 0.85

Calls 12

resolve_introduced_byFunction · 0.85
resolve_positionFunction · 0.85
resolve_inodeFunction · 0.85
add_edge_with_reverseFunction · 0.85
collect_zombie_contextFunction · 0.85
mark_rootedMethod · 0.80
resolve_vertexFunction · 0.70
has_vertexMethod · 0.45
start_posMethod · 0.45
is_folderMethod · 0.45
end_posMethod · 0.45
is_deletedMethod · 0.45

Tested by

no test coverage detected