git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 0/5] Parallel Checkout (part 2)

From
Matheus Tavares <matheus.bernardino@usp.br>
Date
Apr 19, 2021, 00:14 UTC
Message-ID
<cover.1618790794.git.matheus.bernardino@usp.br>
In-Reply-To
<cover.1617893234.git.matheus.bernardino@usp.br>
Three small changes since the last version: 
- In `write_pc_item_to_fd()`, renamed variable 'new_blob' to just 'blob'.
- In `write_pc_item_to_fd()`, used `ce->name` instead of `path` when
  reporting failure to read the object.
- Made `write_pc_item()` unlink() the file on a `write_pc_item_to_fd()`
  error. The reasoning for this is:
  Unlike sequential checkout, the parallel workers create each file
  *before* reading and converting the associated blob, so that they can
  detect path collisions as soon as possible in the process. This is
  important both to avoid unnecessary work reading and filtering
  objects that are not going to be written in parallel, and also to
  avoid reporting errors for colliding entries at the wrong time. These
  entries will be handled in a sequential phase later, and that will be
  the correct time to print any errors regarding their checkout.
  However, these logistics make us leave an empty file behind when we
  find an error after creating the file, e.g. a missing object. The
  added unlink() fix this case while maintaining the other important
  mechanics. The design doc was also adjusted to mention this.
Matheus Tavares (5):
  unpack-trees: add basic support for parallel checkout
  parallel-checkout: make it truly parallel
  parallel-checkout: add configuration options
  parallel-checkout: support progress displaying
  parallel-checkout: add design documentation
 .gitignore                                    |   1 +
 Documentation/Makefile                        |   1 +
 Documentation/config/checkout.txt             |  21 +
 Documentation/technical/parallel-checkout.txt | 271 ++++++++
 Makefile                                      |   2 +
 builtin.h                                     |   1 +
 builtin/checkout--worker.c                    | 145 ++++
 entry.c                                       |  17 +-
 git.c                                         |   2 +
 parallel-checkout.c                           | 655 ++++++++++++++++++
 parallel-checkout.h                           | 111 +++
 unpack-trees.c                                |  19 +-
 12 files changed, 1241 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/technical/parallel-checkout.txt
 create mode 100644 builtin/checkout--worker.c
 create mode 100644 parallel-checkout.c
 create mode 100644 parallel-checkout.h
Range-diff against v2:
1:  0506ac7159 ! 1:  7096822c14 unpack-trees: add basic support for parallel checkout
    @@ parallel-checkout.c (new)
     +	int ret;
     +	struct stream_filter *filter;
     +	struct strbuf buf = STRBUF_INIT;
    -+	char *new_blob;
    ++	char *blob;
     +	unsigned long size;
     +	ssize_t wrote;
     +
    @@ parallel-checkout.c (new)
     +		}
     +	}
     +
    -+	new_blob = read_blob_entry(pc_item->ce, &size);
    -+	if (!new_blob)
    ++	blob = read_blob_entry(pc_item->ce, &size);
    ++	if (!blob)
     +		return error("cannot read object %s '%s'",
    -+			     oid_to_hex(&pc_item->ce->oid), path);
    ++			     oid_to_hex(&pc_item->ce->oid), pc_item->ce->name);
     +
     +	/*
     +	 * checkout metadata is used to give context for external process
    @@ parallel-checkout.c (new)
     +	 * checkout, so pass NULL.
     +	 */
     +	ret = convert_to_working_tree_ca(&pc_item->ca, pc_item->ce->name,
    -+					 new_blob, size, &buf, NULL);
    ++					 blob, size, &buf, NULL);
     +
     +	if (ret) {
     +		size_t newsize;
    -+		free(new_blob);
    -+		new_blob = strbuf_detach(&buf, &newsize);
    ++		free(blob);
    ++		blob = strbuf_detach(&buf, &newsize);
     +		size = newsize;
     +	}
     +
    -+	wrote = write_in_full(fd, new_blob, size);
    -+	free(new_blob);
    ++	wrote = write_in_full(fd, blob, size);
    ++	free(blob);
     +	if (wrote < 0)
     +		return error("unable to write file '%s'", path);
     +
    @@ parallel-checkout.c (new)
     +	if (write_pc_item_to_fd(pc_item, fd, path.buf)) {
     +		/* Error was already reported. */
     +		pc_item->status = PC_ITEM_FAILED;
    ++		close_and_clear(&fd);
    ++		unlink(path.buf);
     +		goto out;
     +	}
     +
    @@ parallel-checkout.c (new)
     +	pc_item->status = PC_ITEM_WRITTEN;
     +
     +out:
    -+	/*
    -+	 * No need to check close() return at this point. Either fd is already
    -+	 * closed, or we are on an error path.
    -+	 */
    -+	close_and_clear(&fd);
     +	strbuf_release(&path);
     +}
     +
2:  0d65b517bd ! 2:  4526516ea0 parallel-checkout: make it truly parallel
    @@ parallel-checkout.c: static int write_pc_item_to_fd(struct parallel_checkout_ite
     +	 * be passed from the main process to the workers.
      	 */
      	ret = convert_to_working_tree_ca(&pc_item->ca, pc_item->ce->name,
    - 					 new_blob, size, &buf, NULL);
    + 					 blob, size, &buf, NULL);
     @@ parallel-checkout.c: static int close_and_clear(int *fd)
      	return ret;
      }
3:  6ea057f9c5 = 3:  ad165c0637 parallel-checkout: add configuration options
4:  0ac4bee67e = 4:  cf9e28dc0e parallel-checkout: support progress displaying
5:  087f8bdf35 ! 5:  415d4114aa parallel-checkout: add design documentation
    @@ Documentation/technical/parallel-checkout.txt (new)
     +Note that, when possible, steps W3 to W5 are delegated to the streaming
     +machinery, removing the need to keep the entire blob in memory.
     +
    -+Also note that the workers *never* remove any file. As mentioned
    -+earlier, it is the responsibility of the main process to remove any file
    -+that blocks the checkout operation (or abort if removing the file(s)
    -+would cause data loss and the user didn't ask to `--force`). This is
    -+crucial to avoid race conditions and also to properly detect path
    -+collisions at Step W1.
    ++If the worker fails to read the blob or to write it to the working tree,
    ++it removes the created file to avoid leaving empty files behind. This is
    ++the *only* time a worker is allowed to remove a file.
    ++
    ++As mentioned earlier, it is the responsibility of the main process to
    ++remove any file that blocks the checkout operation (or abort if the
    ++removal(s) would cause data loss and the user didn't ask to `--force`).
    ++This is crucial to avoid race conditions and also to properly detect
    ++path collisions at Step W1.
     +
     +After the workers finish writing the items and sending back the required
     +information, the main process handles the results in two steps:
-- 
2.30.1
Previous: Christian CouderNext: Matheus Tavares
Message 28 of 40 in “Parallel Checkout (part 2)”
  1. 0/5 Parallel Checkout (part 2)Matheus Tavares, Mar 17, 2021
  2. 1/5 unpack-trees: add basic support for parallel checkoutMatheus Tavares, Mar 17, 2021
  3. Christian CouderMar 31, 2021
  4. Matheus Tavares BernardinoApr 2, 2021
  5. 3/5 parallel-checkout: add configuration optionsMatheus Tavares, Mar 17, 2021
  6. Christian CouderMar 31, 2021
  7. Matheus Tavares BernardinoApr 2, 2021
  8. 5/5 parallel-checkout: add design documentationMatheus Tavares, Mar 17, 2021
  9. Christian CouderMar 31, 2021
  10. 4/5 parallel-checkout: support progress displayingMatheus Tavares, Mar 17, 2021
  11. 2/5 parallel-checkout: make it truly parallelMatheus Tavares, Mar 17, 2021
  12. Christian CouderMar 31, 2021
  13. Matheus Tavares BernardinoApr 2, 2021
  14. Junio C HamanoMar 18, 2021
  15. Matheus TavaresMar 19, 2021
  16. Junio C HamanoMar 19, 2021
  17. Christian CouderMar 31, 2021
  18. 0/5 Parallel Checkout (part 2)Matheus Tavares, Apr 8, 2021
  19. 1/5 unpack-trees: add basic support for parallel checkoutMatheus Tavares, Apr 8, 2021
  20. 2/5 parallel-checkout: make it truly parallelMatheus Tavares, Apr 8, 2021
  21. 3/5 parallel-checkout: add configuration optionsMatheus Tavares, Apr 8, 2021
  22. 4/5 parallel-checkout: support progress displayingMatheus Tavares, Apr 8, 2021
  23. 5/5 parallel-checkout: add design documentationMatheus Tavares, Apr 8, 2021
  24. Junio C HamanoApr 8, 2021
  25. Junio C HamanoApr 16, 2021
  26. Matheus Tavares BernardinoApr 17, 2021
  27. Christian CouderApr 19, 2021
  28. 0/5 Parallel Checkout (part 2)Matheus Tavares, Apr 19, 2021
  29. 1/5 unpack-trees: add basic support for parallel checkoutMatheus Tavares, Apr 19, 2021
  30. 2/5 parallel-checkout: make it truly parallelMatheus Tavares, Apr 19, 2021
  31. 3/5 parallel-checkout: add configuration optionsMatheus Tavares, Apr 19, 2021
  32. 4/5 parallel-checkout: support progress displayingMatheus Tavares, Apr 19, 2021
  33. 5/5 parallel-checkout: add design documentationMatheus Tavares, Apr 19, 2021
  34. Christian CouderApr 19, 2021
  35. 0/5 Parallel Checkout (part 2)Matheus Tavares, Apr 19, 2021
  36. 1/5 unpack-trees: add basic support for parallel checkoutMatheus Tavares, Apr 19, 2021
  37. 2/5 parallel-checkout: make it truly parallelMatheus Tavares, Apr 19, 2021
  38. 3/5 parallel-checkout: add configuration optionsMatheus Tavares, Apr 19, 2021
  39. 4/5 parallel-checkout: support progress displayingMatheus Tavares, Apr 19, 2021
  40. 5/5 parallel-checkout: add design documentationMatheus Tavares, Apr 19, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.