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 <redacted>
---
pack-bitmap.c | 40 +++++++++++++++++++++++++++---
t/t6113-rev-list-bitmap-filters.sh | 7 ++++++
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 196d38c91d..e33805e076 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -925,6 +925,29 @@ static void filter_bitmap_object_type(struct bitmap_index *bitmap_git,
}
}
+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,@@ -932,6 +955,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)@@ -948,8 +973,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,@@ -965,8 +989,16 @@ 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++) {
+ filter_bitmap(bitmap_git, tip_objects, to_filter,
+ &filter->sub[i]);
+ }
+ 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.30.2