@@ -675,23 +675,25 @@ static int forbid_bloom_filters(struct pathspec *spec)
675675{
676676 if (spec -> has_wildcard )
677677 return 1 ;
678- if (spec -> nr > 1 )
679- return 1 ;
680678 if (spec -> magic & ~PATHSPEC_LITERAL )
681679 return 1 ;
682- if (spec -> nr && (spec -> items [0 ].magic & ~PATHSPEC_LITERAL ))
683- return 1 ;
680+ for (size_t nr = 0 ; nr < spec -> nr ; nr ++ )
681+ if (spec -> items [nr ].magic & ~PATHSPEC_LITERAL )
682+ return 1 ;
684683
685684 return 0 ;
686685}
687686
687+ static void release_revisions_bloom_keyvecs (struct rev_info * revs );
688+
688689static void prepare_to_use_bloom_filter (struct rev_info * revs )
689690{
690691 struct pathspec_item * pi ;
692+ struct bloom_keyvec * bloom_keyvec ;
691693 char * path_alloc = NULL ;
692694 const char * path , * p ;
693695 size_t len ;
694- int path_component_nr = 1 ;
696+ int path_component_nr ;
695697
696698 if (!revs -> commits )
697699 return ;
@@ -708,63 +710,73 @@ static void prepare_to_use_bloom_filter(struct rev_info *revs)
708710 if (!revs -> pruning .pathspec .nr )
709711 return ;
710712
711- pi = & revs -> pruning .pathspec .items [0 ];
712-
713- /* remove single trailing slash from path, if needed */
714- if (pi -> len > 0 && pi -> match [pi -> len - 1 ] == '/' ) {
715- path_alloc = xmemdupz (pi -> match , pi -> len - 1 );
716- path = path_alloc ;
717- } else
718- path = pi -> match ;
719-
720- len = strlen (path );
721- if (!len ) {
722- revs -> bloom_filter_settings = NULL ;
723- free (path_alloc );
724- return ;
725- }
713+ revs -> bloom_keyvecs_nr = revs -> pruning .pathspec .nr ;
714+ CALLOC_ARRAY (revs -> bloom_keyvecs , revs -> bloom_keyvecs_nr );
715+ for (int i = 0 ; i < revs -> pruning .pathspec .nr ; i ++ ) {
716+ pi = & revs -> pruning .pathspec .items [i ];
717+ path_component_nr = 1 ;
718+
719+ /* remove single trailing slash from path, if needed */
720+ if (pi -> len > 0 && pi -> match [pi -> len - 1 ] == '/' ) {
721+ path_alloc = xmemdupz (pi -> match , pi -> len - 1 );
722+ path = path_alloc ;
723+ } else
724+ path = pi -> match ;
725+
726+ len = strlen (path );
727+ if (!len )
728+ goto fail ;
729+
730+ p = path ;
731+ while (* p ) {
732+ /*
733+ * At this point, the path is normalized to use
734+ * Unix-style path separators. This is required due to
735+ * how the changed-path Bloom filters store the paths.
736+ */
737+ if (* p == '/' )
738+ path_component_nr ++ ;
739+ p ++ ;
740+ }
726741
727- p = path ;
728- while (* p ) {
729- /*
730- * At this point, the path is normalized to use Unix-style
731- * path separators. This is required due to how the
732- * changed-path Bloom filters store the paths.
733- */
734- if (* p == '/' )
735- path_component_nr ++ ;
736- p ++ ;
737- }
742+ bloom_keyvec = create_bloom_keyvec (path_component_nr );
743+ revs -> bloom_keyvecs [i ] = bloom_keyvec ;
738744
739- revs -> bloom_keys_nr = path_component_nr ;
740- ALLOC_ARRAY (revs -> bloom_keys , revs -> bloom_keys_nr );
745+ fill_bloom_keyvec_key (path , len , bloom_keyvec , 0 ,
746+ revs -> bloom_filter_settings );
747+ path_component_nr = 1 ;
741748
742- fill_bloom_key (path , len , & revs -> bloom_keys [0 ],
743- revs -> bloom_filter_settings );
744- path_component_nr = 1 ;
749+ p = path + len - 1 ;
750+ while (p > path ) {
751+ if (* p == '/' )
752+ fill_bloom_keyvec_key (path , p - path ,
753+ bloom_keyvec ,
754+ path_component_nr ++ ,
755+ revs -> bloom_filter_settings );
756+ p -- ;
757+ }
745758
746- p = path + len - 1 ;
747- while (p > path ) {
748- if (* p == '/' )
749- fill_bloom_key (path , p - path ,
750- & revs -> bloom_keys [path_component_nr ++ ],
751- revs -> bloom_filter_settings );
752- p -- ;
759+ FREE_AND_NULL (path_alloc );
753760 }
754761
755762 if (trace2_is_enabled () && !bloom_filter_atexit_registered ) {
756763 atexit (trace2_bloom_filter_statistics_atexit );
757764 bloom_filter_atexit_registered = 1 ;
758765 }
759766
767+ return ;
768+
769+ fail :
770+ revs -> bloom_filter_settings = NULL ;
760771 free (path_alloc );
772+ release_revisions_bloom_keyvecs (revs );
761773}
762774
763775static int check_maybe_different_in_bloom_filter (struct rev_info * revs ,
764776 struct commit * commit )
765777{
766778 struct bloom_filter * filter ;
767- int result = 1 , j ;
779+ int result = 0 ;
768780
769781 if (!revs -> repo -> objects -> commit_graph )
770782 return -1 ;
@@ -779,10 +791,10 @@ static int check_maybe_different_in_bloom_filter(struct rev_info *revs,
779791 return -1 ;
780792 }
781793
782- for (j = 0 ; result && j < revs -> bloom_keys_nr ; j ++ ) {
783- result = bloom_filter_contains (filter ,
784- & revs -> bloom_keys [ j ],
785- revs -> bloom_filter_settings );
794+ for (size_t nr = 0 ; ! result && nr < revs -> bloom_keyvecs_nr ; nr ++ ) {
795+ result = bloom_filter_contains_vec (filter ,
796+ revs -> bloom_keyvecs [ nr ],
797+ revs -> bloom_filter_settings );
786798 }
787799
788800 if (result )
@@ -823,7 +835,7 @@ static int rev_compare_tree(struct rev_info *revs,
823835 return REV_TREE_SAME ;
824836 }
825837
826- if (revs -> bloom_keys_nr && !nth_parent ) {
838+ if (revs -> bloom_keyvecs_nr && !nth_parent ) {
827839 bloom_ret = check_maybe_different_in_bloom_filter (revs , commit );
828840
829841 if (bloom_ret == 0 )
@@ -850,7 +862,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit,
850862 if (!t1 )
851863 return 0 ;
852864
853- if (!nth_parent && revs -> bloom_keys_nr ) {
865+ if (!nth_parent && revs -> bloom_keyvecs_nr ) {
854866 bloom_ret = check_maybe_different_in_bloom_filter (revs , commit );
855867 if (!bloom_ret )
856868 return 1 ;
@@ -3202,6 +3214,14 @@ static void release_revisions_mailmap(struct string_list *mailmap)
32023214
32033215static void release_revisions_topo_walk_info (struct topo_walk_info * info );
32043216
3217+ static void release_revisions_bloom_keyvecs (struct rev_info * revs )
3218+ {
3219+ for (size_t nr = 0 ; nr < revs -> bloom_keyvecs_nr ; nr ++ )
3220+ destroy_bloom_keyvec (revs -> bloom_keyvecs [nr ]);
3221+ FREE_AND_NULL (revs -> bloom_keyvecs );
3222+ revs -> bloom_keyvecs_nr = 0 ;
3223+ }
3224+
32053225static void free_void_commit_list (void * list )
32063226{
32073227 free_commit_list (list );
@@ -3230,11 +3250,7 @@ void release_revisions(struct rev_info *revs)
32303250 clear_decoration (& revs -> treesame , free );
32313251 line_log_free (revs );
32323252 oidset_clear (& revs -> missing_commits );
3233-
3234- for (int i = 0 ; i < revs -> bloom_keys_nr ; i ++ )
3235- clear_bloom_key (& revs -> bloom_keys [i ]);
3236- FREE_AND_NULL (revs -> bloom_keys );
3237- revs -> bloom_keys_nr = 0 ;
3253+ release_revisions_bloom_keyvecs (revs );
32383254}
32393255
32403256static void add_child (struct rev_info * revs , struct commit * parent , struct commit * child )
0 commit comments