Skip to content

Commit e44c372

Browse files
committed
feat: add Graph::get_or_insert_full_commit()
A way to insert a full commit with a single update functions that has access to the full commit, not just the data.
1 parent 1c44e41 commit e44c372

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

gix-revwalk/src/graph/mod.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ impl<'find, 'cache, T> Graph<'find, 'cache, T> {
226226
}
227227

228228
/// Commit based methods
229-
impl<'find, 'cache, T> Graph<'find, 'cache, crate::graph::Commit<T>> {
230-
/// Lookup `id` without failing if the commit doesn't exist, and assure that `id` is inserted into our set
231-
/// with a commit with `new_data()` assigned.
229+
impl<'find, 'cache, T> Graph<'find, 'cache, Commit<T>> {
230+
/// Lookup `id` in the graph, but insert it if it's not yet present by looking it up without failing if the commit doesn't exist.
231+
/// Call `new_data()` to obtain data for a newly inserted commit.
232232
/// `update_data(data)` gets run either on existing or on new data.
233233
///
234234
/// Note that none of the data updates happen if `id` didn't exist.
@@ -264,8 +264,8 @@ impl<'find, 'cache, T> Graph<'find, 'cache, crate::graph::Commit<T>> {
264264

265265
/// Commit based methods
266266
impl<'find, 'cache, T: Default> Graph<'find, 'cache, Commit<T>> {
267-
/// Lookup `id` without failing if the commit doesn't exist or `id` isn't a commit,
268-
/// and assure that `id` is inserted into our set with a commit and default data assigned.
267+
/// Lookup `id` in the graph, but insert it if it's not yet present by looking it up without failing if the commit doesn't exist.
268+
/// Newly inserted commits are populated with default data.
269269
/// `update_data(data)` gets run either on existing or on new data.
270270
///
271271
/// Note that none of the data updates happen if `id` didn't exist.
@@ -279,6 +279,33 @@ impl<'find, 'cache, T: Default> Graph<'find, 'cache, Commit<T>> {
279279
) -> Result<Option<&mut Commit<T>>, try_lookup_or_insert_default::Error> {
280280
self.try_lookup_or_insert_commit_default(id, T::default, update_data)
281281
}
282+
283+
/// Lookup `id` in the graph, but insert it if it's not yet present by looking it up without failing if the commit doesn't exist.
284+
/// `update_commit(commit)` gets run either on existing or on new data.
285+
///
286+
/// Note that none of the data updates happen if `id` didn't exist in the graph.
287+
pub fn get_or_insert_full_commit(
288+
&mut self,
289+
id: gix_hash::ObjectId,
290+
update_commit: impl FnOnce(&mut Commit<T>),
291+
) -> Result<Option<&mut Commit<T>>, try_lookup_or_insert_default::Error> {
292+
match self.map.entry(id) {
293+
gix_hashtable::hash_map::Entry::Vacant(entry) => {
294+
let res = try_lookup(&id, &*self.find, self.cache, &mut self.buf)?;
295+
let commit = match res {
296+
None => return Ok(None),
297+
Some(commit) => commit,
298+
};
299+
let mut commit = commit.to_owned(T::default)?;
300+
update_commit(&mut commit);
301+
entry.insert(commit);
302+
}
303+
gix_hashtable::hash_map::Entry::Occupied(mut entry) => {
304+
update_commit(entry.get_mut());
305+
}
306+
};
307+
Ok(self.map.get_mut(&id))
308+
}
282309
}
283310

284311
/// Lazy commit access

0 commit comments

Comments
 (0)