Skip to content

Commit 792f811

Browse files
peffgitster
authored andcommitted
rev-list: factor out bitmap-optimized routines
There are a few operations in rev-list that are optimized for bitmaps. Rather than having the code inline in cmd_rev_list(), let's move them into helpers. This not only makes the flow of the main function simpler, but it lets us replace the complex "can we do the optimization?" conditionals with a series of early returns from the functions. That also makes it easy to add comments explaining those conditions. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d90fe06 commit 792f811

File tree

1 file changed

+67
-21
lines changed

1 file changed

+67
-21
lines changed

builtin/rev-list.c

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,69 @@ static inline int parse_missing_action_value(const char *value)
364364
return 0;
365365
}
366366

367+
static int try_bitmap_count(struct rev_info *revs)
368+
{
369+
uint32_t commit_count;
370+
int max_count;
371+
struct bitmap_index *bitmap_git;
372+
373+
/* This function only handles counting, not general traversal. */
374+
if (!revs->count)
375+
return -1;
376+
377+
/*
378+
* A bitmap result can't know left/right, etc, because we don't
379+
* actually traverse.
380+
*/
381+
if (revs->left_right || revs->cherry_mark)
382+
return -1;
383+
384+
/*
385+
* This must be saved before doing any walking, since the revision
386+
* machinery will count it down to zero while traversing.
387+
*/
388+
max_count = revs->max_count;
389+
390+
bitmap_git = prepare_bitmap_walk(revs);
391+
if (!bitmap_git)
392+
return -1;
393+
394+
count_bitmap_commit_list(bitmap_git, &commit_count, NULL, NULL, NULL);
395+
if (max_count >= 0 && max_count < commit_count)
396+
commit_count = max_count;
397+
398+
printf("%d\n", commit_count);
399+
free_bitmap_index(bitmap_git);
400+
return 0;
401+
}
402+
403+
static int try_bitmap_traversal(struct rev_info *revs)
404+
{
405+
struct bitmap_index *bitmap_git;
406+
407+
/*
408+
* We can't use a bitmap result with a traversal limit, since the set
409+
* of commits we'd get would be essentially random.
410+
*/
411+
if (revs->max_count >= 0)
412+
return -1;
413+
414+
/*
415+
* Our bitmap result will return all objects, and we're not
416+
* yet prepared to show only particular types.
417+
*/
418+
if (!revs->tag_objects || !revs->tree_objects || !revs->blob_objects)
419+
return -1;
420+
421+
bitmap_git = prepare_bitmap_walk(revs);
422+
if (!bitmap_git)
423+
return -1;
424+
425+
traverse_bitmap_commit_list(bitmap_git, &show_object_fast);
426+
free_bitmap_index(bitmap_git);
427+
return 0;
428+
}
429+
367430
int cmd_rev_list(int argc, const char **argv, const char *prefix)
368431
{
369432
struct rev_info revs;
@@ -534,27 +597,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
534597
progress = start_delayed_progress(show_progress, 0);
535598

536599
if (use_bitmap_index) {
537-
if (revs.count && !revs.left_right && !revs.cherry_mark) {
538-
uint32_t commit_count;
539-
int max_count = revs.max_count;
540-
struct bitmap_index *bitmap_git;
541-
if ((bitmap_git = prepare_bitmap_walk(&revs))) {
542-
count_bitmap_commit_list(bitmap_git, &commit_count, NULL, NULL, NULL);
543-
if (max_count >= 0 && max_count < commit_count)
544-
commit_count = max_count;
545-
printf("%d\n", commit_count);
546-
free_bitmap_index(bitmap_git);
547-
return 0;
548-
}
549-
} else if (revs.max_count < 0 &&
550-
revs.tag_objects && revs.tree_objects && revs.blob_objects) {
551-
struct bitmap_index *bitmap_git;
552-
if ((bitmap_git = prepare_bitmap_walk(&revs))) {
553-
traverse_bitmap_commit_list(bitmap_git, &show_object_fast);
554-
free_bitmap_index(bitmap_git);
555-
return 0;
556-
}
557-
}
600+
if (!try_bitmap_count(&revs))
601+
return 0;
602+
if (!try_bitmap_traversal(&revs))
603+
return 0;
558604
}
559605

560606
if (prepare_revision_walk(&revs))

0 commit comments

Comments
 (0)