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

Re: [PATCH 05/38] refs: create a base class "ref_store" for files_ref_store

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Jun 9, 2016, 14:10 UTC
Message-ID
<575978DA.30608@alum.mit.edu>
In-Reply-To
<xmqqbn3drkwd.fsf@gitster.mtv.corp.google.com>
On 06/07/2016 07:03 PM, Junio C Hamano wrote:
Show 22 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> We want ref_stores to be polymorphic, so invent a base class of which
>> files_ref_store is a derived class. For now there is a one-to-one
>> relationship between ref_stores and submodules.
> 
> The mention of "submodules" made me go "Huh?" but thinking about it
> for a second it is clear and obvious.  We often peek into refs in a
> different repository that is a submodule, and we do not mix them with
> our own refs.  Logically that is what a "ref store" is, and one-to-one
> relationship is expected.
> 
>> @@ -1284,3 +1288,90 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
>>  	errno = ELOOP;
>>  	return NULL;
>>  }
>> +
>> +static struct ref_store *main_ref_store = NULL;
>> +
>> +static struct ref_store *submodule_ref_stores = NULL;
> 
> Let's let BSS take care of these initialization.

I like the `= NULL` because it expresses "yes, I care about the initial values of these variables", which to me is more valuable than saving a few bytes in the size of the executable. But in fact, GCC does the obvious optimization: it detects that these variables are being initialized to zero, and puts them in BSS anyway. I'd be surprised if other compilers don't do the same. So I'd prefer to leave this as-is, if it's OK with you.

Show 38 quoted lines
>> [...]
>>  /*
>> + * Return a pointer to the reference store for the specified
>> + * submodule. For the main repository, use submodule==NULL; such a
>> + * call cannot fail. For a submodule, the submodule must exist and be
>> + * a nonbare repository, otherwise return NULL. Verify that the
>> + * reference store is a files_ref_store, and cast it to that type
>> + * before returning it.
>>   */
>> +static struct files_ref_store *get_files_ref_store(const char *submodule,
>> +						   const char *caller)
>>  {
>> +	struct ref_store *refs = get_ref_store(submodule);
>>  
>> +	return refs ? files_downcast(refs, 1, caller) : NULL;
>>  }
> 
> This comment may be barking up a wrong tree, but the support for
> class inheritance makes me wonder if I can do something along this
> line:
> 
>  * implement a filesystem based ref_store, that is very similar to
>    what you have as files_ref_store, but 
> 
>    - when storing a ref as a loose ref, or when checking if a ref
>      exists as a loose ref, quote them somehow (e.g. a branch
>      "Branch" is not stored as a file "$GIT_DIR/refs/heads/branch"
>      but by using "^" as a single shift marker, i.e. as
>      "$GIT_DIR/refs/heads/^branch");
> 
>    - when enumerating what refs we have as loose refs, unquote what
>      readdir(3) gave us, e.g. seeing "$GIT_DIR/refs/heads/^branch",
>      I say "there is a branch whose name is 'Branch'".
> 
>  * as locking and other 'methods' are likely to be very similar to
>    your files_ref_store, make this new backend as a subclass of it,
>    i.e. create a new class but function pointers to many methods are
>    copied from files ref_store vtable.

That is definitely something we could implement in the future. If I were going to design an extension like this, I think I'd go straight to something more expressive; maybe something like URL-encoding. For example, we might like a system that can record refnames with a Unicode encoding that is determined by us rather than by the filesystem.

Depending on the details, it might be preferable to implement the new ref-store as an encoding layer that delegates to an old-fashioned files backend rather than using inheritance. In fact, you'd only want to do the translation for the loose storage part, so in the end the implemention might look something like

    overlay_ref_store(
        encoding_ref_store(loose_ref_store()),
        packed_ref_store())
> Would the strict "when downcasting to 'files', we make sure vtable
> is that of 'files' backend" interfere with such an approach?

True, the simple approach that I use above doesn't generalize to implementation inheritance. But I'd rather cross that bridge when we come to it. Implementing an RTTI system in C is a bit ambitious and, I think, comes with runtime costs.

Michael
Previous: Junio C HamanoNext: Junio C Hamano
Message 13 of 67 in “Virtualization of the refs API”
  1. 00/38 Virtualization of the refs APIMichael Haggerty, Jun 3, 2016
  2. 01/38 resolve_gitlink_ref(): eliminate temporary variableMichael Haggerty, Jun 3, 2016
  3. 02/38 rename_ref_available(): add docstringMichael Haggerty, Jun 3, 2016
  4. Junio C HamanoJun 7, 2016
  5. Michael HaggertyJun 9, 2016
  6. Junio C HamanoJun 9, 2016
  7. 03/38 refs: rename struct ref_cache to files_ref_storeMichael Haggerty, Jun 3, 2016
  8. 04/38 refs: add a backend method structureMichael Haggerty, Jun 3, 2016
  9. 05/38 refs: create a base class "ref_store" for files_ref_storeMichael Haggerty, Jun 3, 2016
  10. Junio C HamanoJun 7, 2016
  11. René ScharfeJun 9, 2016
  12. Junio C HamanoJun 7, 2016
  13. Michael HaggertyJun 9, 2016
  14. Junio C HamanoJun 9, 2016
  15. Michael HaggertyJun 10, 2016
  16. Junio C HamanoJun 10, 2016
  17. Eric SunshineJun 10, 2016
  18. Michael HaggertyJun 10, 2016
  19. 06/38 add_packed_ref(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  20. 07/38 get_packed_ref(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  21. 08/38 resolve_missing_loose_ref(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  22. 09/38 {lock,commit,rollback}_packed_refs(): add files_ref_store argumentsMichael Haggerty, Jun 3, 2016
  23. 10/38 refs: add a transaction_commit() methodMichael Haggerty, Jun 3, 2016
  24. 11/38 refs: reorder definitionsMichael Haggerty, Jun 3, 2016
  25. 12/38 resolve_packed_ref(): rename function from resolve_missing_loose_ref()Michael Haggerty, Jun 3, 2016
  26. 13/38 resolve_gitlink_packed_ref(): remove functionMichael Haggerty, Jun 3, 2016
  27. 14/38 read_raw_ref(): take a (struct ref_store *) argumentMichael Haggerty, Jun 3, 2016
  28. 15/38 resolve_ref_recursively(): new functionMichael Haggerty, Jun 3, 2016
  29. 16/38 resolve_gitlink_ref(): implement using resolve_ref_recursively()Michael Haggerty, Jun 3, 2016
  30. Junio C HamanoJun 7, 2016
  31. Eric SunshineJun 14, 2016
  32. Michael HaggertyJun 16, 2016
  33. 17/38 resolve_gitlink_ref(): avoid memory allocation in many casesMichael Haggerty, Jun 3, 2016
  34. Junio C HamanoJun 7, 2016
  35. Michael HaggertyJun 9, 2016
  36. 18/38 resolve_gitlink_ref(): rename path parameter to submoduleMichael Haggerty, Jun 3, 2016
  37. 19/38 refs: make read_raw_ref() virtualMichael Haggerty, Jun 3, 2016
  38. 20/38 refs: make verify_refname_available() virtualMichael Haggerty, Jun 3, 2016
  39. 21/38 refs: make pack_refs() virtualMichael Haggerty, Jun 3, 2016
  40. Junio C HamanoJun 7, 2016
  41. Michael HaggertyJun 9, 2016
  42. 22/38 refs: make create_symref() virtualMichael Haggerty, Jun 3, 2016
  43. 23/38 refs: make peel_ref() virtualMichael Haggerty, Jun 3, 2016
  44. Junio C HamanoJun 7, 2016
  45. Michael HaggertyJun 9, 2016
  46. 24/38 repack_without_refs(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  47. 25/38 lock_raw_ref(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  48. 26/38 commit_ref_update(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  49. 27/38 lock_ref_for_update(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  50. 28/38 lock_ref_sha1_basic(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  51. 29/38 split_symref_update(): add a files_ref_store argumentMichael Haggerty, Jun 3, 2016
  52. 30/38 files_ref_iterator_begin(): take a ref_store argumentMichael Haggerty, Jun 3, 2016
  53. 31/38 refs: add method iterator_beginMichael Haggerty, Jun 3, 2016
  54. 32/38 refs: add methods for reflogMichael Haggerty, Jun 3, 2016
  55. 33/38 refs: add method for initial ref transaction commitMichael Haggerty, Jun 3, 2016
  56. 34/38 refs: add method for delete_refsMichael Haggerty, Jun 3, 2016
  57. Junio C HamanoJun 7, 2016
  58. Michael HaggertyJun 9, 2016
  59. 35/38 refs: add methods to init refs dbMichael Haggerty, Jun 3, 2016
  60. 36/38 refs: add method to rename refsMichael Haggerty, Jun 3, 2016
  61. 37/38 refs: make lock genericMichael Haggerty, Jun 3, 2016
  62. Junio C HamanoJun 7, 2016
  63. Michael HaggertyJun 9, 2016
  64. Michael HaggertyJun 9, 2016
  65. 38/38 refs: implement iteration over only per-worktree refsMichael Haggerty, Jun 3, 2016
  66. Duy NguyenJul 10, 2016
  67. Michael HaggertyJul 13, 2016

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.