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

Re: [PATCH v2 00/10] Use a structure for object IDs.

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 11, 2015, 20:35 UTC
Message-ID
<xmqqk2yn5l39.fsf@gitster.dls.corp.google.com>
In-Reply-To
<5500689A.5090101@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> I think this is a really interesting project and I hope that it works out.
Count me in ;-)
Show 27 quoted lines
> In my opinion, the biggest risk (aside from the sheer amount of work
> required) is the issue that was brought up on the mailing list when you
> submitted v1 [1]: Converting an arbitrary (unsigned char *) to a (struct
> object_id *) is not allowed, because the alignment requirements of the
> latter might be stricter than those of the former. This means that if,
> for example, we are reading some data from disk or from the network, and
> we expect the 20 bytes starting with byte number 17 to be a SHA-1 in
> binary format, we used to be able to do
>
>     unsigned char *sha1 = buf + 17;
>
> and use sha1 like any other SHA-1, without the need for any copying. But
> we can't do the analogous
>
>     struct object_id *oid = (struct object_id *)(buf + 17);
>
> because the alignment is not necessarily correct. So in a pure "struct
> object_id" world, I think we would be forced to change such code to
>
>     struct object_id oid;
>     hashcpy(oid.sha1, buf + 17);
>
> This uses additional memory and introduces copying overhead. Also, the
> lifetime of oid might exceed the scope of a function, so oid might have
> to be allocated on the heap and later freed. This adds more
> computational overhead, more memory overhead, and more programming
> effort to get it all right.

Because we use abstraction to reduce burden on programmers, the last point is really what defeats this approach.

I wonder if there is any way to make the new "oid wrapped in a struct" result in identical binary---that would be a reasonable criterion to judge the goodness of a change line this. Any difference could be (1) compiler being (a) stupid and not taking optimization opportunity it notices for a bare byte array but not for a byte array in struct or (b) clever and taking optimization opportunity the other way around, or (2) breakage in the conversion causing new bugs, perhaps coming from the "alignment" worries you cited above. (1-a) may or may not be an acceptable price to pay for a cleaner abstraction, but that depends on the extent of damage. (1-b) may be unlikely but if there is such a gain, that's nice ;-). And (2) is obviously a show-stopper X-<.

> So as much as I like the idea of wrapping SHA-1s in objects, I think it
> would be a good idea to first make sure that we can all agree on a plan
> for dealing with situations like this. I can think of the following
> possibilities:
These all look sensible to me.
Show 7 quoted lines
> 4. We continue to support working with SHA-1s declared to be (unsigned
> char *) in some performance-critical code, even as we migrate most other
> code to using SHA-1s embedded within a (struct object_id). This will
> cost some duplication of code. To accept this approach, we would need an
> idea of *how much* code duplication would be needed. E.g., how many
> functions will need both (unsigned char *) versions and (struct
> object_id *) versions?

Ideally, only the ones that knows the underlying hash function is SHA-1 (i.e. anybody who mentions git_SHA_CTX), moves bytes from/to in-core object name field and raw range of bytes (e.g. sha1hash()); everybody else like hashcpy() and hashcmp() should be able to do its thing only on structs and a generic-looking constant that denotes how many bytes there are in the hash (or even sizeof(struct oid)).

I do not know what kind of code duplication you are worried about, though. If a callee needs "unsigned char *", the caller that has a "struct object_id *o" should pass o->hash to the callee. We should not add another variant of the same callee that takes a pointer to "struct object_id"---I think that leads to insanty, e.g.

    int hashcmp_o_o(struct object_id *, struct object_id *);
    int hashcmp_o_b(struct object_id *, unsigned char *);
    int hashcmp_b_o(unsigned char *, struct object_id *);
    int hashcmp_b_b(unsigned char *, unsigned char *);

And please do not suggest switching to C++; all it would do to overload these into a single name is to make the callers harder to read.

Previous: Michael HaggertyNext: brian m. carlson
Message 21 of 36 in “Use a structure for object IDs.”
  1. 00/10 Use a structure for object IDs.brian m. carlson, Mar 7, 2015
  2. 01/10 Define a structure for object IDs.brian m. carlson, Mar 7, 2015
  3. 02/10 Define utility functions for object IDs.brian m. carlson, Mar 7, 2015
  4. Duy NguyenMar 8, 2015
  5. brian m. carlsonMar 8, 2015
  6. Michael HaggertyMar 11, 2015
  7. 03/10 bisect.c: convert leaf functions to use struct object_idbrian m. carlson, Mar 7, 2015
  8. 04/10 archive.c: convert to use struct object_idbrian m. carlson, Mar 7, 2015
  9. Michael HaggertyMar 11, 2015
  10. brian m. carlsonMar 11, 2015
  11. 05/10 zip: use GIT_SHA1_HEXSZ for trailersbrian m. carlson, Mar 7, 2015
  12. 06/10 bulk-checkin.c: convert to use struct object_idbrian m. carlson, Mar 7, 2015
  13. 07/10 diff: convert struct combine_diff_path to object_idbrian m. carlson, Mar 7, 2015
  14. 08/10 commit: convert parts to struct object_idbrian m. carlson, Mar 7, 2015
  15. Michael HaggertyMar 11, 2015
  16. 09/10 patch-id: convert to use struct object_idbrian m. carlson, Mar 7, 2015
  17. 10/10 apply: convert threeway_stage to object_idbrian m. carlson, Mar 7, 2015
  18. Junio C HamanoMar 8, 2015
  19. Kyle J. McKayMar 11, 2015
  20. Michael HaggertyMar 11, 2015
  21. Junio C HamanoMar 11, 2015
  22. brian m. carlsonMar 13, 2015
  23. brian m. carlsonMar 11, 2015
  24. Junio C HamanoMar 12, 2015
  25. brian m. carlsonMar 12, 2015
  26. Michael HaggertyMar 12, 2015
  27. brian m. carlsonMar 12, 2015
  28. Duy NguyenMar 12, 2015
  29. Junio C HamanoMar 12, 2015
  30. Junio C HamanoMar 12, 2015
  31. Duy NguyenMar 13, 2015
  32. Junio C HamanoMar 13, 2015
  33. Duy NguyenMar 14, 2015
  34. Junio C HamanoMar 14, 2015
  35. Duy NguyenMar 15, 2015
  36. Junio C HamanoMar 15, 2015

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.