convert: add [async_]convert_to_working_tree_ca() variants

Separate the attribute gathering from the actual conversion by adding _ca() variants of the conversion functions. These variants receive a precomputed 'struct conv_attrs', not relying, thus, on an index state. They will be used in a future patch adding parallel checkout support, for two reasons: - We will already load the conversion attributes in checkout_entry(), before conversion, to decide whether a path is eligible for parallel checkout. Therefore, it would be wasteful to load them again later, for the actual conversion. - The parallel workers will be responsible for reading, converting and writing blobs to the working tree. They won't have access to the main process' index state, so they cannot load the attributes. Instead, they will receive the preloaded ones and call the _ca() variant of the conversion functions. Furthermore, the attributes machinery is optimized to handle paths in sequential order, so it's better to leave it for the main process, anyway. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Dec 16, 2020 at 11:50 UTC 55b4ad0eada6924e5e59600266b5d50cbf22733d
2 files changed +60 -37
convert.c
+32 -28
@@ -1447,19 +1447,16 @@ void convert_to_git_filter_fd(const struct index_state *istate,
1447 ident_to_git(dst->buf, dst->len, dst, ca.ident);
1448 }
1449
1450 -static int convert_to_working_tree_internal(const struct index_state *istate,
1451 - const char *path, const char *src,
1452 - size_t len, struct strbuf *dst,
1453 - int normalizing,
1454 - const struct checkout_metadata *meta,
1455 - struct delayed_checkout *dco)
1450 +static int convert_to_working_tree_ca_internal(const struct conv_attrs *ca,
1451 + const char *path, const char *src,
1452 + size_t len, struct strbuf *dst,
1453 + int normalizing,
1454 + const struct checkout_metadata *meta,
1455 + struct delayed_checkout *dco)
1456 {
1457 int ret = 0, ret_filter = 0;
1458 - struct conv_attrs ca;
1459 -
1460 - convert_attrs(istate, &ca, path);
1458
1462 - ret |= ident_to_worktree(src, len, dst, ca.ident);
1459 + ret |= ident_to_worktree(src, len, dst, ca->ident);
1460 if (ret) {
1461 src = dst->buf;
1462 len = dst->len;
@@ -1469,49 +1466,56 @@ static int convert_to_working_tree_internal(const struct index_state *istate,
1466 * is a smudge or process filter (even if the process filter doesn't
1467 * support smudge). The filters might expect CRLFs.
1468 */
1472 - if ((ca.drv && (ca.drv->smudge || ca.drv->process)) || !normalizing) {
1473 - ret |= crlf_to_worktree(src, len, dst, ca.crlf_action);
1469 + if ((ca->drv && (ca->drv->smudge || ca->drv->process)) || !normalizing) {
1470 + ret |= crlf_to_worktree(src, len, dst, ca->crlf_action);
1471 if (ret) {
1472 src = dst->buf;
1473 len = dst->len;
1474 }
1475 }
1476
1480 - ret |= encode_to_worktree(path, src, len, dst, ca.working_tree_encoding);
1477 + ret |= encode_to_worktree(path, src, len, dst, ca->working_tree_encoding);
1478 if (ret) {
1479 src = dst->buf;
1480 len = dst->len;
1481 }
1482
1483 ret_filter = apply_filter(
1487 - path, src, len, -1, dst, ca.drv, CAP_SMUDGE, meta, dco);
1488 - if (!ret_filter && ca.drv && ca.drv->required)
1489 - die(_("%s: smudge filter %s failed"), path, ca.drv->name);
1484 + path, src, len, -1, dst, ca->drv, CAP_SMUDGE, meta, dco);
1485 + if (!ret_filter && ca->drv && ca->drv->required)
1486 + die(_("%s: smudge filter %s failed"), path, ca->drv->name);
1487
1488 return ret | ret_filter;
1489 }
1490
1494 -int async_convert_to_working_tree(const struct index_state *istate,
1495 - const char *path, const char *src,
1496 - size_t len, struct strbuf *dst,
1497 - const struct checkout_metadata *meta,
1498 - void *dco)
1491 +int async_convert_to_working_tree_ca(const struct conv_attrs *ca,
1492 + const char *path, const char *src,
1493 + size_t len, struct strbuf *dst,
1494 + const struct checkout_metadata *meta,
1495 + void *dco)
1496 {
1500 - return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, dco);
1497 + return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0,
1498 + meta, dco);
1499 }
1500
1503 -int convert_to_working_tree(const struct index_state *istate,
1504 - const char *path, const char *src,
1505 - size_t len, struct strbuf *dst,
1506 - const struct checkout_metadata *meta)
1501 +int convert_to_working_tree_ca(const struct conv_attrs *ca,
1502 + const char *path, const char *src,
1503 + size_t len, struct strbuf *dst,
1504 + const struct checkout_metadata *meta)
1505 {
1508 - return convert_to_working_tree_internal(istate, path, src, len, dst, 0, meta, NULL);
1506 + return convert_to_working_tree_ca_internal(ca, path, src, len, dst, 0,
1507 + meta, NULL);
1508 }
1509
1510 int renormalize_buffer(const struct index_state *istate, const char *path,
1511 const char *src, size_t len, struct strbuf *dst)
1512 {
1514 - int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL, NULL);
1513 + struct conv_attrs ca;
1514 + int ret;
1515 +
1516 + convert_attrs(istate, &ca, path);
1517 + ret = convert_to_working_tree_ca_internal(&ca, path, src, len, dst, 1,
1518 + NULL, NULL);
1519 if (ret) {
1520 src = dst->buf;
1521 len = dst->len;
convert.h
+28 -9
@@ -99,15 +99,34 @@ const char *get_convert_attr_ascii(const struct index_state *istate,
99 int convert_to_git(const struct index_state *istate,
100 const char *path, const char *src, size_t len,
101 struct strbuf *dst, int conv_flags);
102 -int convert_to_working_tree(const struct index_state *istate,
103 - const char *path, const char *src,
104 - size_t len, struct strbuf *dst,
105 - const struct checkout_metadata *meta);
106 -int async_convert_to_working_tree(const struct index_state *istate,
107 - const char *path, const char *src,
108 - size_t len, struct strbuf *dst,
109 - const struct checkout_metadata *meta,
110 - void *dco);
102 +int convert_to_working_tree_ca(const struct conv_attrs *ca,
103 + const char *path, const char *src,
104 + size_t len, struct strbuf *dst,
105 + const struct checkout_metadata *meta);
106 +int async_convert_to_working_tree_ca(const struct conv_attrs *ca,
107 + const char *path, const char *src,
108 + size_t len, struct strbuf *dst,
109 + const struct checkout_metadata *meta,
110 + void *dco);
111 +static inline int convert_to_working_tree(const struct index_state *istate,
112 + const char *path, const char *src,
113 + size_t len, struct strbuf *dst,
114 + const struct checkout_metadata *meta)
115 +{
116 + struct conv_attrs ca;
117 + convert_attrs(istate, &ca, path);
118 + return convert_to_working_tree_ca(&ca, path, src, len, dst, meta);
119 +}
120 +static inline int async_convert_to_working_tree(const struct index_state *istate,
121 + const char *path, const char *src,
122 + size_t len, struct strbuf *dst,
123 + const struct checkout_metadata *meta,
124 + void *dco)
125 +{
126 + struct conv_attrs ca;
127 + convert_attrs(istate, &ca, path);
128 + return async_convert_to_working_tree_ca(&ca, path, src, len, dst, meta, dco);
129 +}
130 int async_query_available_blobs(const char *cmd,
131 struct string_list *available_paths);
132 int renormalize_buffer(const struct index_state *istate,