entry: move conv_attrs lookup up to checkout_entry()

In a following patch, checkout_entry() will use conv_attrs to decide whether an entry should be enqueued for parallel checkout or not. But the attributes lookup only happens lower in this call stack. To avoid the unnecessary work of loading the attributes twice, let's move it up to checkout_entry(), and pass the loaded struct down to write_entry(). Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matheus Tavares committed Mar 23, 2021 at 11:19 UTC 30419e7e1d53232bb83dcace200d1295b326b22b
1 file changed +27 -11
entry.c
+27 -11
@@ -263,8 +263,9 @@ void update_ce_after_write(const struct checkout *state, struct cache_entry *ce,
263 }
264 }
265
266 -static int write_entry(struct cache_entry *ce,
267 - char *path, const struct checkout *state, int to_tempfile)
266 +/* Note: ca is used (and required) iff the entry refers to a regular file. */
267 +static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca,
268 + const struct checkout *state, int to_tempfile)
269 {
270 unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
271 struct delayed_checkout *dco = state->delayed_checkout;
@@ -281,8 +282,7 @@ static int write_entry(struct cache_entry *ce,
282 clone_checkout_metadata(&meta, &state->meta, &ce->oid);
283
284 if (ce_mode_s_ifmt == S_IFREG) {
284 - struct stream_filter *filter = get_stream_filter(state->istate, ce->name,
285 - &ce->oid);
285 + struct stream_filter *filter = get_stream_filter_ca(ca, &ce->oid);
286 if (filter &&
287 !streaming_write_entry(ce, path, filter,
288 state, to_tempfile,
@@ -329,14 +329,17 @@ static int write_entry(struct cache_entry *ce,
329 * Convert from git internal format to working tree format
330 */
331 if (dco && dco->state != CE_NO_DELAY) {
332 - ret = async_convert_to_working_tree(state->istate, ce->name, new_blob,
333 - size, &buf, &meta, dco);
332 + ret = async_convert_to_working_tree_ca(ca, ce->name,
333 + new_blob, size,
334 + &buf, &meta, dco);
335 if (ret && string_list_has_string(&dco->paths, ce->name)) {
336 free(new_blob);
337 goto delayed;
338 }
338 - } else
339 - ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf, &meta);
339 + } else {
340 + ret = convert_to_working_tree_ca(ca, ce->name, new_blob,
341 + size, &buf, &meta);
342 + }
343
344 if (ret) {
345 free(new_blob);
@@ -442,6 +445,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
445 {
446 static struct strbuf path = STRBUF_INIT;
447 struct stat st;
448 + struct conv_attrs ca_buf, *ca = NULL;
449
450 if (ce->ce_flags & CE_WT_REMOVE) {
451 if (topath)
@@ -454,8 +458,13 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
458 return 0;
459 }
460
457 - if (topath)
458 - return write_entry(ce, topath, state, 1);
461 + if (topath) {
462 + if (S_ISREG(ce->ce_mode)) {
463 + convert_attrs(state->istate, &ca_buf, ce->name);
464 + ca = &ca_buf;
465 + }
466 + return write_entry(ce, topath, ca, state, 1);
467 + }
468
469 strbuf_reset(&path);
470 strbuf_add(&path, state->base_dir, state->base_dir_len);
@@ -517,9 +526,16 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
526 return 0;
527
528 create_directories(path.buf, path.len, state);
529 +
530 if (nr_checkouts)
531 (*nr_checkouts)++;
522 - return write_entry(ce, path.buf, state, 0);
532 +
533 + if (S_ISREG(ce->ce_mode)) {
534 + convert_attrs(state->istate, &ca_buf, ce->name);
535 + ca = &ca_buf;
536 + }
537 +
538 + return write_entry(ce, path.buf, ca, state, 0);
539 }
540
541 void unlink_entry(const struct cache_entry *ce)