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

Method find_block_end

atomic-core/src/pristine/txn/write/graph.rs:149–213  ·  view source on GitHub ↗

Find a block that ends at or after the given position. This is used for predecessors resolution where we need to find the span that ENDS at a position, not one that contains it. This is important when creating edges from an existing span to a new one. # Arguments `pos` - The position to find (typically the end of a context span) # Returns The span that ends at or after the given position, or

(&self, pos: Position<NodeId>)

Source from the content-addressed store, hash-verified

147 /// - Empty vertices (start == end == pos) are matched exactly
148 /// - For non-empty vertices, finds one where start < pos <= end
149 fn find_block_end(&self, pos: Position<NodeId>) -> PristineResult<GraphNode<NodeId>> {
150 // Handle ROOT position specially
151 if pos.change.is_root() {
152 return Ok(GraphNode::ROOT);
153 }
154
155 let table = self.txn.open_multimap_table(GRAPH)?;
156
157 let change_id = pos.change.get();
158 let target_pos = pos.pos.get();
159
160 // FIRST: Check for empty span at exact position using direct lookup.
161 // This is important because empty vertices like inode markers (e.g., V[9:9])
162 // must be found when predecessors references position 9, even if there's
163 // another span like V[0:9] that also ends at position 9.
164 // Without this direct lookup, iteration would return V[0:9] first since
165 // it has a lower start position.
166 let empty_key = encode_vertex(change_id, target_pos, target_pos);
167 if table.get(&empty_key)?.next().is_some() {
168 return Ok(GraphNode {
169 change: NodeId::new(change_id),
170 start: ChangePosition::new(target_pos),
171 end: ChangePosition::new(target_pos),
172 });
173 }
174
175 // SECOND: Fall back to iteration to find vertices that end at this position
176 let start_key = encode_vertex(change_id, 0, 0);
177 let end_key = encode_vertex(change_id, u64::MAX, u64::MAX);
178
179 // Look for a span that ends at this position
180 for result in table.range::<&[u8; 24]>(&start_key..=&end_key)? {
181 let (key, _values) = result?;
182 let (v_change, v_start, v_end) = decode_vertex(key.value());
183
184 if v_change != change_id {
185 continue;
186 }
187
188 // Check for span that ends at this position
189 // For predecessors, we want the span where end == target_pos
190 if v_end == target_pos && v_start < v_end {
191 return Ok(GraphNode {
192 change: NodeId::new(v_change),
193 start: ChangePosition::new(v_start),
194 end: ChangePosition::new(v_end),
195 });
196 }
197
198 // Also check if position falls within [start, end]
199 // This handles the case where we're looking for a span containing this position
200 if v_start <= target_pos && target_pos < v_end {
201 return Ok(GraphNode {
202 change: NodeId::new(v_change),
203 start: ChangePosition::new(v_start),
204 end: ChangePosition::new(v_end),
205 });
206 }

Callers

nothing calls this directly

Calls 5

encode_vertexFunction · 0.85
decode_vertexFunction · 0.85
getMethod · 0.65
is_rootMethod · 0.45
nextMethod · 0.45

Tested by

no test coverage detected