@@ -90,11 +90,26 @@ impl<'find, T> Graph<'find, T> {
90
90
self . map . get_mut ( id)
91
91
}
92
92
93
- /// Insert `id` into the graph and associate it with `value`, returning the previous value associated with it if it existed.
93
+ /// Insert `id` into the graph and associate it with `value`, returning the previous value associated with `id` if it existed.
94
94
pub fn insert ( & mut self , id : gix_hash:: ObjectId , value : T ) -> Option < T > {
95
95
self . map . insert ( id, value)
96
96
}
97
97
98
+ /// Insert `id` into the graph and associate it with the value returned by `make_data`,
99
+ /// and returning the previous value associated with `id` if it existed.
100
+ /// Fail if `id` doesn't exist in the object database.
101
+ pub fn insert_data < E > (
102
+ & mut self ,
103
+ id : gix_hash:: ObjectId ,
104
+ mut make_data : impl FnMut ( LazyCommit < ' _ > ) -> Result < T , E > ,
105
+ ) -> Result < Option < T > , E >
106
+ where
107
+ E : From < gix_object:: find:: existing_iter:: Error > ,
108
+ {
109
+ let value = make_data ( self . lookup ( & id) . map_err ( E :: from) ?) ?;
110
+ Ok ( self . map . insert ( id, value) )
111
+ }
112
+
98
113
/// Remove all data from the graph to start over.
99
114
pub fn clear ( & mut self ) {
100
115
self . map . clear ( ) ;
@@ -136,6 +151,45 @@ impl<'find, T> Graph<'find, T> {
136
151
Ok ( ( ) )
137
152
}
138
153
154
+ /// Insert the parents of commit named `id` to the graph and associate new parents with data
155
+ /// as produced by `parent_data(parent_id, parent_info, maybe-existing-data &mut T) -> T`, which is always
156
+ /// provided the full parent commit information.
157
+ /// It will be provided either existing data, along with complete information about the parent,
158
+ /// and produces new data even though it's only used in case the parent isn't stored in the graph yet.
159
+ #[ allow( clippy:: type_complexity) ]
160
+ pub fn insert_parents_with_lookup < E > (
161
+ & mut self ,
162
+ id : & gix_hash:: oid ,
163
+ parent_data : & mut dyn FnMut ( gix_hash:: ObjectId , LazyCommit < ' _ > , Option < & mut T > ) -> Result < T , E > ,
164
+ ) -> Result < ( ) , E >
165
+ where
166
+ E : From < gix_object:: find:: existing_iter:: Error >
167
+ + From < gix_object:: decode:: Error >
168
+ + From < commit:: iter_parents:: Error > ,
169
+ {
170
+ let commit = self . lookup ( id) . map_err ( E :: from) ?;
171
+ let parents: SmallVec < [ _ ; 2 ] > = commit. iter_parents ( ) . collect ( ) ;
172
+ for parent_id in parents {
173
+ let parent_id = parent_id. map_err ( E :: from) ?;
174
+ let parent = match try_lookup ( & parent_id, & * self . find , self . cache . as_ref ( ) , & mut self . parent_buf )
175
+ . map_err ( E :: from) ?
176
+ {
177
+ Some ( p) => p,
178
+ None => continue , // skip missing objects, this is due to shallow clones for instance.
179
+ } ;
180
+
181
+ match self . map . entry ( parent_id) {
182
+ gix_hashtable:: hash_map:: Entry :: Vacant ( entry) => {
183
+ entry. insert ( parent_data ( parent_id, parent, None ) ?) ;
184
+ }
185
+ gix_hashtable:: hash_map:: Entry :: Occupied ( mut entry) => {
186
+ parent_data ( parent_id, parent, Some ( entry. get_mut ( ) ) ) ?;
187
+ }
188
+ }
189
+ }
190
+ Ok ( ( ) )
191
+ }
192
+
139
193
/// Turn ourselves into the underlying graph structure, which is a mere mapping between object ids and their data.
140
194
pub fn detach ( self ) -> IdMap < T > {
141
195
self . map
0 commit comments