@@ -5,14 +5,47 @@ use smallvec::SmallVec;
5
5
6
6
use crate :: Graph ;
7
7
8
- /// A mapping between an object id and arbitrary data, and produced when calling [`Graph::detach`].
8
+ /// A mapping between an object id and arbitrary data, and produced when calling [`Graph::detach() `].
9
9
pub type IdMap < T > = gix_hashtable:: HashMap < gix_hash:: ObjectId , T > ;
10
10
11
11
///
12
12
pub mod commit;
13
13
14
- mod errors;
15
- pub use errors:: { insert_parents, lookup} ;
14
+ mod errors {
15
+ ///
16
+ pub mod insert_parents {
17
+ use crate :: graph:: commit:: iter_parents;
18
+
19
+ /// The error returned by [`insert_parents()`](crate::Graph::insert_parents()).
20
+ #[ derive( Debug , thiserror:: Error ) ]
21
+ #[ allow( missing_docs) ]
22
+ pub enum Error {
23
+ #[ error( transparent) ]
24
+ Lookup ( #[ from] gix_object:: find:: existing_iter:: Error ) ,
25
+ #[ error( "A commit could not be decoded during traversal" ) ]
26
+ Decode ( #[ from] gix_object:: decode:: Error ) ,
27
+ #[ error( transparent) ]
28
+ Parent ( #[ from] iter_parents:: Error ) ,
29
+ }
30
+ }
31
+
32
+ ///
33
+ pub mod try_lookup_or_insert_default {
34
+ use crate :: graph:: commit:: to_owned;
35
+
36
+ /// The error returned by [`try_lookup_or_insert_default()`](crate::Graph::try_lookup_or_insert_default()).
37
+ #[ derive( Debug , thiserror:: Error ) ]
38
+ #[ allow( missing_docs) ]
39
+ pub enum Error {
40
+ #[ error( transparent) ]
41
+ Lookup ( #[ from] gix_object:: find:: existing_iter:: Error ) ,
42
+ #[ error( transparent) ]
43
+ ToOwned ( #[ from] to_owned:: Error ) ,
44
+ }
45
+ }
46
+ }
47
+ pub use errors:: { insert_parents, try_lookup_or_insert_default} ;
48
+
16
49
use gix_date:: SecondsSinceUnixEpoch ;
17
50
18
51
/// The generation away from the HEAD of graph, useful to limit algorithms by topological depth as well.
@@ -36,7 +69,7 @@ impl<'find, T: Default> Graph<'find, T> {
36
69
& mut self ,
37
70
id : gix_hash:: ObjectId ,
38
71
update_data : impl FnOnce ( & mut T ) ,
39
- ) -> Result < Option < LazyCommit < ' _ > > , lookup :: Error > {
72
+ ) -> Result < Option < LazyCommit < ' _ > > , try_lookup_or_insert_default :: Error > {
40
73
self . try_lookup_or_insert_default ( id, T :: default, update_data)
41
74
}
42
75
}
@@ -85,9 +118,7 @@ impl<'find, T> Graph<'find, T> {
85
118
let parent_id = parent_id?;
86
119
match self . map . entry ( parent_id) {
87
120
gix_hashtable:: hash_map:: Entry :: Vacant ( entry) => {
88
- let parent = match try_lookup ( & parent_id, & mut self . find , self . cache . as_ref ( ) , & mut self . parent_buf )
89
- . map_err ( |err| insert_parents:: Error :: Lookup ( lookup:: existing:: Error :: Find ( err) ) ) ?
90
- {
121
+ let parent = match try_lookup ( & parent_id, & * self . find , self . cache . as_ref ( ) , & mut self . parent_buf ) ? {
91
122
Some ( p) => p,
92
123
None => continue , // skip missing objects, this is due to shallow clones for instance.
93
124
} ;
@@ -114,26 +145,17 @@ impl<'find, T> Graph<'find, T> {
114
145
115
146
/// Initialization
116
147
impl < ' find , T > Graph < ' find , T > {
117
- /// Create a new instance with `find ` to retrieve commits and optionally `cache` to accelerate commit access.
148
+ /// Create a new instance with `objects ` to retrieve commits and optionally `cache` to accelerate commit access.
118
149
///
119
150
/// ### Performance
120
151
///
121
152
/// `find` should be optimized to access the same object repeatedly, ideally with an object cache to keep the last couple of
122
153
/// most recently used commits.
123
154
/// Furthermore, **none-existing commits should not trigger the pack-db to be refreshed.** Otherwise, performance may be sub-optimal
124
155
/// in shallow repositories as running into non-existing commits will trigger a refresh of the `packs` directory.
125
- pub fn new < Find > ( find : Find , cache : impl Into < Option < gix_commitgraph:: Graph > > ) -> Self
126
- where
127
- Find : for < ' a > FnMut (
128
- & gix_hash:: oid ,
129
- & ' a mut Vec < u8 > ,
130
- ) -> Result <
131
- Option < gix_object:: CommitRefIter < ' a > > ,
132
- Box < dyn std:: error:: Error + Send + Sync + ' static > ,
133
- > + ' find ,
134
- {
156
+ pub fn new ( objects : impl gix_object:: Find + ' find , cache : impl Into < Option < gix_commitgraph:: Graph > > ) -> Self {
135
157
Graph {
136
- find : Box :: new ( find ) ,
158
+ find : Box :: new ( objects ) ,
137
159
cache : cache. into ( ) ,
138
160
map : gix_hashtable:: HashMap :: default ( ) ,
139
161
buf : Vec :: new ( ) ,
@@ -154,10 +176,10 @@ impl<'find, T> Graph<'find, Commit<T>> {
154
176
id : gix_hash:: ObjectId ,
155
177
new_data : impl FnOnce ( ) -> T ,
156
178
update_data : impl FnOnce ( & mut T ) ,
157
- ) -> Result < Option < & mut Commit < T > > , lookup :: commit :: Error > {
179
+ ) -> Result < Option < & mut Commit < T > > , try_lookup_or_insert_default :: Error > {
158
180
match self . map . entry ( id) {
159
181
gix_hashtable:: hash_map:: Entry :: Vacant ( entry) => {
160
- let res = try_lookup ( & id, & mut self . find , self . cache . as_ref ( ) , & mut self . buf ) ?;
182
+ let res = try_lookup ( & id, & * self . find , self . cache . as_ref ( ) , & mut self . buf ) ?;
161
183
let commit = match res {
162
184
None => return Ok ( None ) ,
163
185
Some ( commit) => commit,
@@ -176,8 +198,8 @@ impl<'find, T> Graph<'find, Commit<T>> {
176
198
177
199
/// commit access
178
200
impl < ' find , T : Default > Graph < ' find , Commit < T > > {
179
- /// Lookup `id` without failing if the commit doesn't exist, and assure that `id` is inserted into our set
180
- /// with a commit and default data assigned.
201
+ /// Lookup `id` without failing if the commit doesn't exist or `id` isn't a commit,
202
+ /// and assure that `id` is inserted into our set with a commit and default data assigned.
181
203
/// `update_data(data)` gets run either on existing or on new data.
182
204
///
183
205
/// Note that none of the data updates happen if `id` didn't exist.
@@ -188,14 +210,15 @@ impl<'find, T: Default> Graph<'find, Commit<T>> {
188
210
& mut self ,
189
211
id : gix_hash:: ObjectId ,
190
212
update_data : impl FnOnce ( & mut T ) ,
191
- ) -> Result < Option < & mut Commit < T > > , lookup :: commit :: Error > {
213
+ ) -> Result < Option < & mut Commit < T > > , try_lookup_or_insert_default :: Error > {
192
214
self . try_lookup_or_insert_commit_default ( id, T :: default, update_data)
193
215
}
194
216
}
195
217
196
218
/// Lazy commit access
197
219
impl < ' find , T > Graph < ' find , T > {
198
- /// Lookup `id` without failing if the commit doesn't exist, and assure that `id` is inserted into our set
220
+ /// Lookup `id` without failing if the commit doesn't exist or `id` isn't a commit,
221
+ /// and assure that `id` is inserted into our set
199
222
/// with a `default` value assigned to it.
200
223
/// `update_data(data)` gets run either on existing or no new data.
201
224
/// Return the commit when done.
@@ -209,8 +232,8 @@ impl<'find, T> Graph<'find, T> {
209
232
id : gix_hash:: ObjectId ,
210
233
default : impl FnOnce ( ) -> T ,
211
234
update_data : impl FnOnce ( & mut T ) ,
212
- ) -> Result < Option < LazyCommit < ' _ > > , lookup :: Error > {
213
- let res = try_lookup ( & id, & mut self . find , self . cache . as_ref ( ) , & mut self . buf ) ?;
235
+ ) -> Result < Option < LazyCommit < ' _ > > , try_lookup_or_insert_default :: Error > {
236
+ let res = try_lookup ( & id, & * self . find , self . cache . as_ref ( ) , & mut self . buf ) ?;
214
237
Ok ( res. map ( |commit| {
215
238
match self . map . entry ( id) {
216
239
gix_hashtable:: hash_map:: Entry :: Vacant ( entry) => {
@@ -226,25 +249,31 @@ impl<'find, T> Graph<'find, T> {
226
249
} ) )
227
250
}
228
251
229
- /// Try to lookup `id` and return a handle to it for accessing its data, but don't fail if the commit doesn't exist.
252
+ /// Try to lookup `id` and return a handle to it for accessing its data, but don't fail if the commit doesn't exist
253
+ /// or isn't a commit.
230
254
///
231
255
/// It's possible that commits don't exist if the repository is shallow.
232
- pub fn try_lookup ( & mut self , id : & gix_hash:: oid ) -> Result < Option < LazyCommit < ' _ > > , lookup:: Error > {
233
- try_lookup ( id, & mut self . find , self . cache . as_ref ( ) , & mut self . buf )
256
+ pub fn try_lookup (
257
+ & mut self ,
258
+ id : & gix_hash:: oid ,
259
+ ) -> Result < Option < LazyCommit < ' _ > > , gix_object:: find:: existing_iter:: Error > {
260
+ try_lookup ( id, & * self . find , self . cache . as_ref ( ) , & mut self . buf )
234
261
}
235
262
236
- /// Lookup `id` and return a handle to it, or fail if it doesn't exist.
237
- pub fn lookup ( & mut self , id : & gix_hash:: oid ) -> Result < LazyCommit < ' _ > , lookup:: existing:: Error > {
238
- self . try_lookup ( id) ?. ok_or ( lookup:: existing:: Error :: Missing )
263
+ /// Lookup `id` and return a handle to it, or fail if it doesn't exist or is no commit.
264
+ pub fn lookup ( & mut self , id : & gix_hash:: oid ) -> Result < LazyCommit < ' _ > , gix_object:: find:: existing_iter:: Error > {
265
+ Ok ( self
266
+ . try_lookup ( id) ?
267
+ . ok_or ( gix_object:: find:: existing_iter:: Error :: NotFound { oid : id. to_owned ( ) } ) ?)
239
268
}
240
269
}
241
270
242
271
fn try_lookup < ' graph > (
243
272
id : & gix_hash:: oid ,
244
- find : & mut Box < FindFn < ' _ > > ,
273
+ objects : & dyn gix_object :: Find ,
245
274
cache : Option < & ' graph gix_commitgraph:: Graph > ,
246
275
buf : & ' graph mut Vec < u8 > ,
247
- ) -> Result < Option < LazyCommit < ' graph > > , lookup :: Error > {
276
+ ) -> Result < Option < LazyCommit < ' graph > > , gix_object :: find :: existing_iter :: Error > {
248
277
if let Some ( cache) = cache {
249
278
if let Some ( pos) = cache. lookup ( id) {
250
279
return Ok ( Some ( LazyCommit {
@@ -253,12 +282,17 @@ fn try_lookup<'graph>(
253
282
}
254
283
}
255
284
#[ allow( clippy:: manual_map) ]
256
- Ok ( match find ( id, buf) ? {
257
- Some ( _) => Some ( LazyCommit {
258
- backing : Either :: Left ( buf) ,
259
- } ) ,
260
- None => None ,
261
- } )
285
+ Ok (
286
+ match objects
287
+ . try_find ( id, buf)
288
+ . map_err ( gix_object:: find:: existing_iter:: Error :: Find ) ?
289
+ {
290
+ Some ( data) => data. kind . is_commit ( ) . then_some ( LazyCommit {
291
+ backing : Either :: Left ( buf) ,
292
+ } ) ,
293
+ None => None ,
294
+ } ,
295
+ )
262
296
}
263
297
264
298
impl < ' a , ' find , T > Index < & ' a gix_hash:: oid > for Graph < ' find , T > {
@@ -316,13 +350,6 @@ pub struct LazyCommit<'graph> {
316
350
backing : Either < & ' graph [ u8 ] , ( & ' graph gix_commitgraph:: Graph , gix_commitgraph:: Position ) > ,
317
351
}
318
352
319
- pub ( crate ) type FindFn < ' find > = dyn for < ' a > FnMut (
320
- & gix_hash:: oid ,
321
- & ' a mut Vec < u8 > ,
322
- )
323
- -> Result < Option < gix_object:: CommitRefIter < ' a > > , Box < dyn std:: error:: Error + Send + Sync + ' static > >
324
- + ' find ;
325
-
326
353
enum Either < T , U > {
327
354
Left ( T ) ,
328
355
Right ( U ) ,
0 commit comments