Message ID | 7e28323b624ad2d8d12123783f00f5a8fbb248e8.1626204784.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Optimization batch 14: trivial directory resolution | expand |
On 7/13/2021 3:33 PM, Elijah Newren via GitGitGadget wrote: > From: Elijah Newren <newren@gmail.com> > > In order to allow trivial directory resolution, we first need to be able > to gather more information to determine if the optimization is safe. To > enable that, we need a way of deferring the recursion into the directory > until a later time. Naturally, deferring the entry into a subtree means > that we need some function that will later recurse into the subdirectory > exactly the same way that collect_merge_info_callback() would have done. > > Add a helper function that does this. For now this function is not used > but a subsequent commit will change that. Future commits will also make > the function sometimes resolve directories instead of traversing inside. ...> +MAYBE_UNUSED > +static int handle_deferred_entries(struct merge_options *opt, > + struct traverse_info *info) > +{ > + struct rename_info *renames = &opt->priv->renames; > + struct hashmap_iter iter; > + struct strmap_entry *entry; > + int side, ret = 0; > + > + for (side = MERGE_SIDE1; side <= MERGE_SIDE2; side++) { > + renames->trivial_merges_okay[side] = 0; We are unconditionally setting this to zero? I will await the use of the method to see how that affects things. > + strintmap_for_each_entry(&renames->possible_trivial_merges[side], > + &iter, entry) { The rest of this loop seems like standard logic for handling these tree walks. Thanks, -Stolee
On Thu, Jul 15, 2021 at 7:32 AM Derrick Stolee <stolee@gmail.com> wrote: > > On 7/13/2021 3:33 PM, Elijah Newren via GitGitGadget wrote: > > From: Elijah Newren <newren@gmail.com> > > > > In order to allow trivial directory resolution, we first need to be able > > to gather more information to determine if the optimization is safe. To > > enable that, we need a way of deferring the recursion into the directory > > until a later time. Naturally, deferring the entry into a subtree means > > that we need some function that will later recurse into the subdirectory > > exactly the same way that collect_merge_info_callback() would have done. > > > > Add a helper function that does this. For now this function is not used > > but a subsequent commit will change that. Future commits will also make > > the function sometimes resolve directories instead of traversing inside. > ...> +MAYBE_UNUSED > > +static int handle_deferred_entries(struct merge_options *opt, > > + struct traverse_info *info) > > +{ > > + struct rename_info *renames = &opt->priv->renames; > > + struct hashmap_iter iter; > > + struct strmap_entry *entry; > > + int side, ret = 0; > > + > > + for (side = MERGE_SIDE1; side <= MERGE_SIDE2; side++) { > > + renames->trivial_merges_okay[side] = 0; > > We are unconditionally setting this to zero? I will await the > use of the method to see how that affects things. Unconditionally set to 0 because at this point in the series we don't yet have the logic to handle it. This line will be replaced later once we add the necessary logic. > > > + strintmap_for_each_entry(&renames->possible_trivial_merges[side], > > + &iter, entry) { > > The rest of this loop seems like standard logic for handling > these tree walks. > > Thanks, > -Stolee
diff --git a/merge-ort.c b/merge-ort.c index 3d3f00b3b45..eb0e18d7546 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1196,6 +1196,70 @@ static int collect_merge_info_callback(int n, return mask; } +MAYBE_UNUSED +static int handle_deferred_entries(struct merge_options *opt, + struct traverse_info *info) +{ + struct rename_info *renames = &opt->priv->renames; + struct hashmap_iter iter; + struct strmap_entry *entry; + int side, ret = 0; + + for (side = MERGE_SIDE1; side <= MERGE_SIDE2; side++) { + renames->trivial_merges_okay[side] = 0; + strintmap_for_each_entry(&renames->possible_trivial_merges[side], + &iter, entry) { + const char *path = entry->key; + unsigned dir_rename_mask = (intptr_t)entry->value; + struct conflict_info *ci; + unsigned dirmask; + struct tree_desc t[3]; + void *buf[3] = {NULL,}; + int i; + + ci = strmap_get(&opt->priv->paths, path); + VERIFY_CI(ci); + dirmask = ci->dirmask; + + info->name = path; + info->namelen = strlen(path); + info->pathlen = info->namelen + 1; + + for (i = 0; i < 3; i++, dirmask >>= 1) { + if (i == 1 && ci->match_mask == 3) + t[1] = t[0]; + else if (i == 2 && ci->match_mask == 5) + t[2] = t[0]; + else if (i == 2 && ci->match_mask == 6) + t[2] = t[1]; + else { + const struct object_id *oid = NULL; + if (dirmask & 1) + oid = &ci->stages[i].oid; + buf[i] = fill_tree_descriptor(opt->repo, + t+i, oid); + } + } + + ci->match_mask &= ci->filemask; + opt->priv->current_dir_name = path; + renames->dir_rename_mask = dir_rename_mask; + if (renames->dir_rename_mask == 0 || + renames->dir_rename_mask == 0x07) + ret = traverse_trees(NULL, 3, t, info); + else + ret = traverse_trees_wrapper(NULL, 3, t, info); + + for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) + free(buf[i]); + + if (ret < 0) + return ret; + } + } + return ret; +} + static int collect_merge_info(struct merge_options *opt, struct tree *merge_base, struct tree *side1,