23
23
#include "list-objects.h"
24
24
#include "commit-slab.h"
25
25
#include "wildmatch.h"
26
+ #include "prio-queue.h"
26
27
27
28
#define MAX_TAGS (FLAG_BITS - 1)
28
29
#define DEFAULT_CANDIDATES 10
@@ -249,32 +250,70 @@ static int compare_pt(const void *a_, const void *b_)
249
250
return 0 ;
250
251
}
251
252
252
- static unsigned long finish_depth_computation (
253
- struct commit_list * * list ,
254
- struct possible_tag * best )
253
+ struct lazy_queue {
254
+ struct prio_queue queue ;
255
+ bool get_pending ;
256
+ };
257
+
258
+ #define LAZY_QUEUE_INIT { { compare_commits_by_commit_date }, false }
259
+
260
+ static void * lazy_queue_get (struct lazy_queue * queue )
261
+ {
262
+ if (queue -> get_pending )
263
+ prio_queue_get (& queue -> queue );
264
+ else
265
+ queue -> get_pending = true;
266
+ return prio_queue_peek (& queue -> queue );
267
+ }
268
+
269
+ static void lazy_queue_put (struct lazy_queue * queue , void * thing )
270
+ {
271
+ if (queue -> get_pending )
272
+ prio_queue_replace (& queue -> queue , thing );
273
+ else
274
+ prio_queue_put (& queue -> queue , thing );
275
+ queue -> get_pending = false;
276
+ }
277
+
278
+ static bool lazy_queue_empty (const struct lazy_queue * queue )
279
+ {
280
+ return queue -> queue .nr == (queue -> get_pending ? 1 : 0 );
281
+ }
282
+
283
+ static void lazy_queue_clear (struct lazy_queue * queue )
284
+ {
285
+ clear_prio_queue (& queue -> queue );
286
+ queue -> get_pending = false;
287
+ }
288
+
289
+ static bool all_have_flag (const struct lazy_queue * queue , unsigned flag )
290
+ {
291
+ for (size_t i = queue -> get_pending ? 1 : 0 ; i < queue -> queue .nr ; i ++ ) {
292
+ struct commit * commit = queue -> queue .array [i ].data ;
293
+ if (!(commit -> object .flags & flag ))
294
+ return false;
295
+ }
296
+ return true;
297
+ }
298
+
299
+ static unsigned long finish_depth_computation (struct lazy_queue * queue ,
300
+ struct possible_tag * best )
255
301
{
256
302
unsigned long seen_commits = 0 ;
257
- while (* list ) {
258
- struct commit * c = pop_commit ( list );
303
+ while (! lazy_queue_empty ( queue ) ) {
304
+ struct commit * c = lazy_queue_get ( queue );
259
305
struct commit_list * parents = c -> parents ;
260
306
seen_commits ++ ;
261
307
if (c -> object .flags & best -> flag_within ) {
262
- struct commit_list * a = * list ;
263
- while (a ) {
264
- struct commit * i = a -> item ;
265
- if (!(i -> object .flags & best -> flag_within ))
266
- break ;
267
- a = a -> next ;
268
- }
269
- if (!a )
308
+ if (all_have_flag (queue , best -> flag_within ))
270
309
break ;
271
310
} else
272
311
best -> depth ++ ;
273
312
while (parents ) {
274
313
struct commit * p = parents -> item ;
275
314
repo_parse_commit (the_repository , p );
276
315
if (!(p -> object .flags & SEEN ))
277
- commit_list_insert_by_date ( p , list );
316
+ lazy_queue_put ( queue , p );
278
317
p -> object .flags |= c -> object .flags ;
279
318
parents = parents -> next ;
280
319
}
@@ -316,7 +355,7 @@ static void append_suffix(int depth, const struct object_id *oid, struct strbuf
316
355
static void describe_commit (struct object_id * oid , struct strbuf * dst )
317
356
{
318
357
struct commit * cmit , * gave_up_on = NULL ;
319
- struct commit_list * list ;
358
+ struct lazy_queue queue = LAZY_QUEUE_INIT ;
320
359
struct commit_name * n ;
321
360
struct possible_tag all_matches [MAX_TAGS ];
322
361
unsigned int match_cnt = 0 , annotated_cnt = 0 , cur_match ;
@@ -359,11 +398,10 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
359
398
have_util = 1 ;
360
399
}
361
400
362
- list = NULL ;
363
401
cmit -> object .flags = SEEN ;
364
- commit_list_insert ( cmit , & list );
365
- while (list ) {
366
- struct commit * c = pop_commit ( & list );
402
+ lazy_queue_put ( & queue , cmit );
403
+ while (! lazy_queue_empty ( & queue ) ) {
404
+ struct commit * c = lazy_queue_get ( & queue );
367
405
struct commit_list * parents = c -> parents ;
368
406
struct commit_name * * slot ;
369
407
@@ -397,7 +435,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
397
435
t -> depth ++ ;
398
436
}
399
437
/* Stop if last remaining path already covered by best candidate(s) */
400
- if (annotated_cnt && ! list ) {
438
+ if (annotated_cnt && lazy_queue_empty ( & queue ) ) {
401
439
int best_depth = INT_MAX ;
402
440
unsigned best_within = 0 ;
403
441
for (cur_match = 0 ; cur_match < match_cnt ; cur_match ++ ) {
@@ -420,7 +458,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
420
458
struct commit * p = parents -> item ;
421
459
repo_parse_commit (the_repository , p );
422
460
if (!(p -> object .flags & SEEN ))
423
- commit_list_insert_by_date ( p , & list );
461
+ lazy_queue_put ( & queue , p );
424
462
p -> object .flags |= c -> object .flags ;
425
463
parents = parents -> next ;
426
464
@@ -435,6 +473,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
435
473
strbuf_add_unique_abbrev (dst , cmit_oid , abbrev );
436
474
if (suffix )
437
475
strbuf_addstr (dst , suffix );
476
+ lazy_queue_clear (& queue );
438
477
return ;
439
478
}
440
479
if (unannotated_cnt )
@@ -450,11 +489,11 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
450
489
QSORT (all_matches , match_cnt , compare_pt );
451
490
452
491
if (gave_up_on ) {
453
- commit_list_insert_by_date ( gave_up_on , & list );
492
+ lazy_queue_put ( & queue , gave_up_on );
454
493
seen_commits -- ;
455
494
}
456
- seen_commits += finish_depth_computation (& list , & all_matches [0 ]);
457
- free_commit_list ( list );
495
+ seen_commits += finish_depth_computation (& queue , & all_matches [0 ]);
496
+ lazy_queue_clear ( & queue );
458
497
459
498
if (debug ) {
460
499
static int label_width = -1 ;
0 commit comments