@matheusbsbs / matheus-bagliano / commits / 792f811998
Fork 0

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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Feb 14, 2020 at 13:22 UTC 792f8119986bd354eb4ea0858dfd45904120c257
1 file changed +67 -21
builtin/rev-list.c
+67 -21
@@ -364,6 +364,69 @@ static inline int parse_missing_action_value(const char *value)
364 return 0;
365 }
366
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 +
430 int cmd_rev_list(int argc, const char **argv, const char *prefix)
431 {
432 struct rev_info revs;
@@ -534,27 +597,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
597 progress = start_delayed_progress(show_progress, 0);
598
599 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;
604 }
605
606 if (prepare_revision_walk(&revs))