[PATCH v3 7/8] pack-bitmap: implement combined filter
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Apr 9, 2021, 11:28 UTC
- Message-ID
- <06a376399bcce0caed993fd2e1a9cff5a57ce502.1617967252.git.ps@pks.im>
- In-Reply-To
- <cover.1617967252.git.ps@pks.im>
When the user has multiple objects filters specified, then this is internally represented by having a "combined" filter. These combined filters aren't yet supported by bitmap indices and can thus not be accelerated.
Fix this by implementing support for these combined filters. The implementation is quite trivial: when there's a combined filter, we simply recurse into `filter_bitmap()` for all of the sub-filters.
Signed-off-by: Patrick Steinhardt <ps@pks.im> --- pack-bitmap.c | 41 +++++++++++++++++++++++++++--- t/t6113-rev-list-bitmap-filters.sh | 7 +++++ 2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/pack-bitmap.c b/pack-bitmap.c index cd3f5c433e..4385f15828 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -926,6 +926,29 @@ static void filter_bitmap_object_type(struct bitmap_index *bitmap_git, filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_BLOB); } +static int filter_supported(struct list_objects_filter_options *filter) +{ + int i; + + switch (filter->choice) { + case LOFC_BLOB_NONE: + case LOFC_BLOB_LIMIT: + case LOFC_OBJECT_TYPE: + return 1; + case LOFC_TREE_DEPTH: + if (filter->tree_exclude_depth == 0) + return 1; + return 0; + case LOFC_COMBINE: + for (i = 0; i < filter->sub_nr; i++) + if (!filter_supported(&filter->sub[i])) + return 0; + return 1; + default: + return 0; + } +} + static int filter_bitmap(struct bitmap_index *bitmap_git, struct object_list *tip_objects, struct bitmap *to_filter, @@ -933,6 +956,8 @@ static int filter_bitmap(struct bitmap_index *bitmap_git, { if (!filter || filter->choice == LOFC_DISABLED) return 0; + if (!filter_supported(filter)) + return -1; if (filter->choice == LOFC_BLOB_NONE) { if (bitmap_git) @@ -949,8 +974,7 @@ static int filter_bitmap(struct bitmap_index *bitmap_git, return 0; } - if (filter->choice == LOFC_TREE_DEPTH && - filter->tree_exclude_depth == 0) { + if (filter->choice == LOFC_TREE_DEPTH) { if (bitmap_git) filter_bitmap_tree_depth(bitmap_git, tip_objects, to_filter, @@ -966,8 +990,17 @@ static int filter_bitmap(struct bitmap_index *bitmap_git, return 0; } - /* filter choice not handled */ - return -1; + if (filter->choice == LOFC_COMBINE) { + int i; + for (i = 0; i < filter->sub_nr; i++) { + if (filter_bitmap(bitmap_git, tip_objects, to_filter, + &filter->sub[i]) < 0) + return -1; + } + return 0; + } + + BUG("unsupported filter choice"); } static int can_filter_bitmap(struct list_objects_filter_options *filter) diff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh index fb66735ac8..cb9db7df6f 100755 --- a/t/t6113-rev-list-bitmap-filters.sh +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -98,4 +98,11 @@ test_expect_success 'object:type filter' ' test_bitmap_traversal expect actual ' +test_expect_success 'combine filter' ' + git rev-list --objects --filter=blob:limit=1000 --filter=object:type=blob tag >expect && + git rev-list --use-bitmap-index \ + --objects --filter=blob:limit=1000 --filter=object:type=blob tag >actual && + test_bitmap_traversal expect actual +' + test_done
-- 2.31.1