Now that the pseudo-merge machinery has learned how to select non-bitmapped commits and assign them into different pseudo-merge group(s), invoke this new API from within the pack-bitmap internals and store the results off. Note that the selected pseudo-merge commits aren't actually used or written anywhere yet. This will be done in the following commit. Signed-off-by: Taylor Blau <me@xxxxxxxxxxxx> --- Documentation/config.txt | 2 + Documentation/config/bitmap-pseudo-merge.txt | 75 ++++++++++++++++++++ Documentation/technical/bitmap-format.txt | 26 +++++++ pack-bitmap-write.c | 14 ++++ 4 files changed, 117 insertions(+) create mode 100644 Documentation/config/bitmap-pseudo-merge.txt diff --git a/Documentation/config.txt b/Documentation/config.txt index 70b448b1326..bbedb7b9a06 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -383,6 +383,8 @@ include::config/apply.txt[] include::config/attr.txt[] +include::config/bitmap-pseudo-merge.txt[] + include::config/blame.txt[] include::config/branch.txt[] diff --git a/Documentation/config/bitmap-pseudo-merge.txt b/Documentation/config/bitmap-pseudo-merge.txt new file mode 100644 index 00000000000..90b72522046 --- /dev/null +++ b/Documentation/config/bitmap-pseudo-merge.txt @@ -0,0 +1,75 @@ +bitmapPseudoMerge.<name>.pattern:: + Regular expression used to match reference names. Commits + pointed to by references matching this pattern (and meeting + the below criteria, like `bitmapPseudoMerge.<name>.sampleRate` + and `bitmapPseudoMerge.<name>.threshold`) will be considered + for inclusion in a pseudo-merge bitmap. ++ +Commits are grouped into pseudo-merge groups based on whether or not +any reference(s) that point at a given commit match the pattern, which +is an extended regular expression. ++ +Within a pseudo-merge group, commits may be further grouped into +sub-groups based on the capture groups in the pattern. These +sub-groupings are formed from the regular expressions by concatenating +any capture groups from the regular expression, with a '-' dash in +between. ++ +For example, if the pattern is `refs/tags/`, then all tags (provided +they meet the below criteria) will be considered candidates for the +same pseudo-merge group. However, if the pattern is instead +`refs/remotes/([0-9])+/tags/`, then tags from different remotes will +be grouped into separate pseudo-merge groups, based on the remote +number. + +bitmapPseudoMerge.<name>.decay:: + Determines the rate at which consecutive pseudo-merge bitmap + groups decrease in size. Must be non-negative. This parameter + can be thought of as `k` in the function `f(n) = C * + n^(-k/100)`, where `f(n)` is the size of the `n`th group. ++ +Setting the decay rate equal to `0` will cause all groups to be the +same size. Setting the decay rate equal to `100` will cause the `n`th +group to be `1/n` the size of the initial group. Higher values of the +decay rate cause consecutive groups to shrink at an increasing rate. +The default is `100`. + +bitmapPseudoMerge.<name>.sampleRate:: + Determines the proportion of non-bitmapped commits (among + reference tips) which are selected for inclusion in an + unstable pseudo-merge bitmap. Must be between `0` and `100` + (inclusive). The default is `100`. + +bitmapPseudoMerge.<name>.threshold:: + Determines the minimum age of non-bitmapped commits (among + reference tips, as above) which are candidates for inclusion + in an unstable pseudo-merge bitmap. The default is + `1.week.ago`. + +bitmapPseudoMerge.<name>.maxMerges:: + Determines the maximum number of pseudo-merge commits among + which commits may be distributed. ++ +For pseudo-merge groups whose pattern does not contain any capture +groups, this setting is applied for all commits matching the regular +expression. For patterns that have one or more capture groups, this +setting is applied for each distinct capture group. ++ +For example, if your capture group is `refs/tags/`, then this setting +will distribute all tags into a maximum of `maxMerges` pseudo-merge +commits. However, if your capture group is, say, +`refs/remotes/([0-9]+)/tags/`, then this setting will be applied to +each remote's set of tags individually. ++ +Must be non-negative. The default value is 64. + +bitmapPseudoMerge.<name>.stableThreshold:: + Determines the minimum age of commits (among reference tips, + as above, however stable commits are still considered + candidates even when they have been covered by a bitmap) which + are candidates for a stable a pseudo-merge bitmap. The default + is `1.month.ago`. + +bitmapPseudoMerge.<name>.stableSize:: + Determines the size (in number of commits) of a stable + psuedo-merge bitmap. The default is `512`. diff --git a/Documentation/technical/bitmap-format.txt b/Documentation/technical/bitmap-format.txt index 63a7177ac08..ed7edf98034 100644 --- a/Documentation/technical/bitmap-format.txt +++ b/Documentation/technical/bitmap-format.txt @@ -434,3 +434,29 @@ the end of a `.bitmap` file. The format is as follows: * An 8-byte unsigned value (in network byte-order) equal to the number of bytes in the pseudo-merge section (including this field). + +=== Pseudo-merge selection + +Pseudo-merge commits are selected among non-bitmapped commits at the +tip of one or more reference(s). In addition, there are a handful of +constraints to further refine this selection: + +`pack.bitmapPseudoMergeDecay`:: Defines the "decay rate", which +corresponds to how quickly (or not) consecutive pseudo-merges decrease +in size relative to one another. + +`pack.bitmapPseudoMergeGroups`:: Defines the maximum number of +pseudo-merge groups. + +`pack.bitmapPseudoMergeSampleRate`:: Defines the percentage of commits +(matching the above criteria) which are selected. + +`pack.bitmapPseudoMergeThreshold`:: Defines the minimum age of a commit +in order to be considered for inclusion within one or more pseudo-merge +bitmaps. + +The size of consecutive pseudo-merge groups decays according to a +power-law decay function, where the size of the `n`-th group is `f(n) = +C*n^-k`. The value of `C` is chosen accordingly to match the number of +desired groups, and `k` is 1/100th of the value of +`pack.bitmapPseudoMergeDecay`. diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index dab5bdea806..e06930e10b9 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -17,6 +17,7 @@ #include "trace2.h" #include "tree.h" #include "tree-walk.h" +#include "pseudo-merge.h" struct bitmapped_commit { struct commit *commit; @@ -39,6 +40,8 @@ struct bitmap_writer { struct bitmapped_commit *selected; unsigned int selected_nr, selected_alloc; + struct string_list pseudo_merge_groups; + kh_oid_map_t *pseudo_merge_commits; /* oid -> pseudo merge(s) */ uint32_t pseudo_merges_nr; struct progress *progress; @@ -56,6 +59,11 @@ static inline int bitmap_writer_selected_nr(void) void bitmap_writer_init(struct repository *r) { writer.bitmaps = kh_init_oid_map(); + writer.pseudo_merge_commits = kh_init_oid_map(); + + string_list_init_dup(&writer.pseudo_merge_groups); + + load_pseudo_merges_from_config(&writer.pseudo_merge_groups); } void bitmap_writer_show_progress(int show) @@ -686,6 +694,12 @@ void bitmap_writer_select_commits(struct commit **indexed_commits, } stop_progress(&writer.progress); + + select_pseudo_merges(&writer.pseudo_merge_groups, + indexed_commits, indexed_commits_nr, + writer.pseudo_merge_commits, + &writer.pseudo_merges_nr, + writer.show_progress); } -- 2.45.0.23.gc6f94b99219