Skip to content

Commit 5420901

Browse files
pks-tgitster
authored andcommitted
pack-bitmap: add function to iterate over filtered bitmapped objects
Introduce a function that allows the caller to iterate over all bitmapped objects that match a given filter. This mechanism will be used in a subsequent commit to optimize object filters in git-cat-file(1). Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3d45483 commit 5420901

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

pack-bitmap.c

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,7 @@ static void init_type_iterator(struct ewah_or_iterator *it,
16621662

16631663
static void show_objects_for_type(
16641664
struct bitmap_index *bitmap_git,
1665+
struct bitmap *objects,
16651666
enum object_type object_type,
16661667
show_reachable_fn show_reach,
16671668
void *payload)
@@ -1672,8 +1673,6 @@ static void show_objects_for_type(
16721673
struct ewah_or_iterator it;
16731674
eword_t filter;
16741675

1675-
struct bitmap *objects = bitmap_git->result;
1676-
16771676
init_type_iterator(&it, bitmap_git, object_type);
16781677

16791678
for (i = 0; i < objects->word_alloc &&
@@ -2025,6 +2024,50 @@ static void filter_packed_objects_from_bitmap(struct bitmap_index *bitmap_git,
20252024
}
20262025
}
20272026

2027+
int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
2028+
struct list_objects_filter_options *filter,
2029+
show_reachable_fn show_reach,
2030+
void *payload)
2031+
{
2032+
struct bitmap *filtered_bitmap = NULL;
2033+
uint32_t objects_nr;
2034+
size_t full_word_count;
2035+
int ret;
2036+
2037+
if (!can_filter_bitmap(filter)) {
2038+
ret = -1;
2039+
goto out;
2040+
}
2041+
2042+
objects_nr = bitmap_num_objects(bitmap_git);
2043+
full_word_count = objects_nr / BITS_IN_EWORD;
2044+
2045+
/* We start from the all-1 bitmap and then filter down from there. */
2046+
filtered_bitmap = bitmap_word_alloc(full_word_count + !!(objects_nr % BITS_IN_EWORD));
2047+
memset(filtered_bitmap->words, 0xff, full_word_count * sizeof(*filtered_bitmap->words));
2048+
for (size_t i = full_word_count * BITS_IN_EWORD; i < objects_nr; i++)
2049+
bitmap_set(filtered_bitmap, i);
2050+
2051+
if (filter_bitmap(bitmap_git, NULL, filtered_bitmap, filter) < 0) {
2052+
ret = -1;
2053+
goto out;
2054+
}
2055+
2056+
show_objects_for_type(bitmap_git, filtered_bitmap,
2057+
OBJ_COMMIT, show_reach, payload);
2058+
show_objects_for_type(bitmap_git, filtered_bitmap,
2059+
OBJ_TREE, show_reach, payload);
2060+
show_objects_for_type(bitmap_git, filtered_bitmap,
2061+
OBJ_BLOB, show_reach, payload);
2062+
show_objects_for_type(bitmap_git, filtered_bitmap,
2063+
OBJ_TAG, show_reach, payload);
2064+
2065+
ret = 0;
2066+
out:
2067+
bitmap_free(filtered_bitmap);
2068+
return ret;
2069+
}
2070+
20282071
struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
20292072
int filter_provided_objects)
20302073
{
@@ -2519,13 +2562,17 @@ void traverse_bitmap_commit_list(struct bitmap_index *bitmap_git,
25192562
{
25202563
assert(bitmap_git->result);
25212564

2522-
show_objects_for_type(bitmap_git, OBJ_COMMIT, show_reachable, NULL);
2565+
show_objects_for_type(bitmap_git, bitmap_git->result,
2566+
OBJ_COMMIT, show_reachable, NULL);
25232567
if (revs->tree_objects)
2524-
show_objects_for_type(bitmap_git, OBJ_TREE, show_reachable, NULL);
2568+
show_objects_for_type(bitmap_git, bitmap_git->result,
2569+
OBJ_TREE, show_reachable, NULL);
25252570
if (revs->blob_objects)
2526-
show_objects_for_type(bitmap_git, OBJ_BLOB, show_reachable, NULL);
2571+
show_objects_for_type(bitmap_git, bitmap_git->result,
2572+
OBJ_BLOB, show_reachable, NULL);
25272573
if (revs->tag_objects)
2528-
show_objects_for_type(bitmap_git, OBJ_TAG, show_reachable, NULL);
2574+
show_objects_for_type(bitmap_git, bitmap_git->result,
2575+
OBJ_TAG, show_reachable, NULL);
25292576

25302577
show_extended_objects(bitmap_git, revs, show_reachable);
25312578
}

pack-bitmap.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ int test_bitmap_pseudo_merges(struct repository *r);
7979
int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n);
8080
int test_bitmap_pseudo_merge_objects(struct repository *r, uint32_t n);
8181

82+
struct list_objects_filter_options;
83+
84+
/*
85+
* Filter bitmapped objects and iterate through all resulting objects,
86+
* executing `show_reach` for each of them. Returns `-1` in case the filter is
87+
* not supported, `0` otherwise.
88+
*/
89+
int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
90+
struct list_objects_filter_options *filter,
91+
show_reachable_fn show_reach,
92+
void *payload);
93+
8294
#define GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL \
8395
"GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL"
8496

0 commit comments

Comments
 (0)