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

Re: [PATCH v3 00/27] Revamp the attribute system; another round

From
BWBrandon Williams <bmwill@google.com>
Date
Feb 9, 2017, 17:18 UTC
Message-ID
<20170209171804.GA61274@google.com>
In-Reply-To
<xmqqwpd8s8vd.fsf@gitster.mtv.corp.google.com>
On 02/02, Junio C Hamano wrote:
Show 21 quoted lines
> 	prepare the <question, answer> array
> 	for path taken from some set:
> 		do_something(the array, path)
> 
> That way, do_something() do not have to keep allocating,
> initializing and destroying the array.
> 
> But after looking at the current set of codepaths, before coming to
> the conclusion that we need to split the static part that is
> specific to the callsite for git_check_attr() and the dynamic part
> that is specific to the <callsite, thread> pair, I noticed that
> typically the callers that can prepare the array before going into
> the loop (which will eventually be spread across multiple threads)
> are many levels away in the callchain, and they are not even aware
> of what attributes are going to be requested in the leaf level
> helper functions.  In other words, the approach to hoist "the
> <question, answer> array" up in the callchain would not scale.  A
> caller that loops over paths in the index and check them out does
> not want to know (and we do not want to tell it) what exact
> attributes are involved in the decision convert_to_working_tree()
> makes for each path, for example.

This was something that I was envisioning as well, though I didn't dig very deep into the call stack. Another means of doing this could be to have the attr_check structure allocated and then have it configured at a later point for the particular question being asked:

  alloc struct attr_check c;
  ... many call sites down
  configure(c, questions)
  for path
    do_something(c, path)

That also allows the same structure to be reused (just reconfigured) if different attributes are needed at a later point in time. Of course this is just an idea and I'm not sure if this is the best way to do it either.

Show 47 quoted lines
> 
> So how would we split questions and answers in a way that is not
> naive and inefficient?  
> 
> I envision that we would allow the attribute subsystem to keep track
> of the dynamic part, which will receive the answers, holds working
> area like check_all_attr[], and has the equivalent to the "attr
> stack", indexed by <thread-id, callsite> pair (and the
> identification of "callsite" can be done by using the address of the
> static part, i.e. the array of questions that we initialize just
> once when interning the list of attribute names for the first time).
> 
> The API to prepare and ask for attributes may look like:
> 
> 	static struct attr_static_part Q;
> 	struct attr_dynamic_part *D;
> 
> 	attr_check_init(&Q, "text", ...);
> 	D = git_attr_check(&Q, path);
> 
> where Q contains an array of interned attributes (i.e. questions)
> and other immutable things that is unique to this callsite, but can
> be shared across multiple threads asking the same question from
> here.  As an internal implementation detail, it probably will have a
> mutex to make sure that init will run only once.
> 
> Then the implementation of git_attr_check(&Q, path) would be:
> 
>     - see if there is already the "dynaic part" allocated for the
>       current thread asking the question Q.  If there is not,
>       allocate one and remember it, so that it can be reused in
>       later calls by the same thread; if there is, use that existing
>       one.
> 
>     - reinitialize the "dynamic part" as needed, e.g. clear the
>       equivalent to check_all_attr[], adjust the equivalent to
>       attr_stack for the current path, etc.  Just like the current
>       code optimizes for the case where the entire program (a single
>       thread) will ask the same question for paths in traversal
>       order (i.e. falling in the same directory), this will optimize
>       for the access pattern where each thread asks the same
>       question for paths in its traversal order.
> 
>     - do what the current collect_some_attrs() thing does.
> 
> And this hopefully won't be as costly as the naive and inefficient
> one.

I agree, this sort of implementation wouldn't suffer from the same allocation penalty that the naive implementation suffers from. This would be slightly challenging to ensure that there aren't any memory leaks, well not leaks but rather memory that isn't freed. i.e. When a thread terminates we would want to reclaim the memory used for the dynamic part which is stored inside the attribute system.

Show 12 quoted lines
> 
> The reason why I was pushing hard to split the static part and the
> dynamic part in our redesign of the API is primarily because I didn't
> want to update the API callers twice.  But I'd imagine that your v3
> (and your earlier "do not discard attr stack, but keep them around,
> holding their tips in a hashmap for quick reuse") would at least lay
> the foundation for the eventual shape of the API, let's bite the
> bullet and accept that we will need to update the callers again
> anyway.
> 
> Thanks.
> 

At least v3 gets the attribute system to a state where further improvements should be relatively easy to make. And now as long as each thread has a unique attr_check structure, multiple callers can exist inside the attribute system at the same time. There is still more work to be done on it though. Still my biggest complaint is the "direction" aspect of the system. I would love to also eliminate that as global state at some point though I'm not sure how at this point.

-- 
Brandon Williams
Previous: Junio C HamanoNext: Junio C Hamano
Message 110 of 111 in “Revamp the attribute system; another round”
  1. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 12, 2017
  2. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 12, 2017
  3. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 12, 2017
  4. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 12, 2017
  5. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 12, 2017
  6. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 12, 2017
  7. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 12, 2017
  8. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 12, 2017
  9. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 12, 2017
  10. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 12, 2017
  11. Stefan BellerJan 18, 2017
  12. Brandon WilliamsJan 18, 2017
  13. 25/27 attr: store attribute stacks in hashmapBrandon Williams, Jan 12, 2017
  14. Junio C HamanoJan 13, 2017
  15. Brandon WilliamsJan 18, 2017
  16. Brandon WilliamsJan 23, 2017
  17. Stefan BellerJan 18, 2017
  18. Brandon WilliamsJan 18, 2017
  19. Stefan BellerJan 18, 2017
  20. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 12, 2017
  21. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 12, 2017
  22. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 12, 2017
  23. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 12, 2017
  24. 12/27 Documentation: fix a typoBrandon Williams, Jan 12, 2017
  25. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 12, 2017
  26. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 12, 2017
  27. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 12, 2017
  28. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 12, 2017
  29. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 12, 2017
  30. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 12, 2017
  31. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 12, 2017
  32. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 12, 2017
  33. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 12, 2017
  34. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 12, 2017
  35. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 12, 2017
  36. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 12, 2017
  37. Junio C HamanoJan 15, 2017
  38. Jeff KingJan 16, 2017
  39. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 23, 2017
  40. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 23, 2017
  41. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 23, 2017
  42. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 23, 2017
  43. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 23, 2017
  44. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 23, 2017
  45. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 23, 2017
  46. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 23, 2017
  47. 12/27 Documentation: fix a typoBrandon Williams, Jan 23, 2017
  48. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 23, 2017
  49. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 23, 2017
  50. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 23, 2017
  51. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 23, 2017
  52. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 23, 2017
  53. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 23, 2017
  54. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 23, 2017
  55. Junio C HamanoJan 23, 2017
  56. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 23, 2017
  57. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 23, 2017
  58. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 23, 2017
  59. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 23, 2017
  60. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 23, 2017
  61. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 23, 2017
  62. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 23, 2017
  63. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 23, 2017
  64. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 23, 2017
  65. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 23, 2017
  66. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 23, 2017
  67. 25/27 attr: store attribute stack in attr_check structureBrandon Williams, Jan 23, 2017
  68. Junio C HamanoJan 23, 2017
  69. Brandon WilliamsJan 23, 2017
  70. Brandon WilliamsJan 24, 2017
  71. Junio C HamanoJan 24, 2017
  72. Brandon WilliamsJan 25, 2017
  73. Stefan BellerJan 25, 2017
  74. Junio C HamanoJan 25, 2017
  75. Brandon WilliamsJan 25, 2017
  76. Brandon WilliamsJan 25, 2017
  77. 00/27 Revamp the attribute system; another roundBrandon Williams, Jan 28, 2017
  78. 01/27 commit.c: use strchrnul() to scan for one lineBrandon Williams, Jan 28, 2017
  79. 02/27 attr.c: use strchrnul() to scan for one lineBrandon Williams, Jan 28, 2017
  80. 05/27 attr.c: complete a sentence in a commentBrandon Williams, Jan 28, 2017
  81. 03/27 attr.c: update a stale comment on "struct match_attr"Brandon Williams, Jan 28, 2017
  82. 07/27 attr.c: simplify macroexpand_one()Brandon Williams, Jan 28, 2017
  83. 06/27 attr.c: mark where #if DEBUG ends more clearlyBrandon Williams, Jan 28, 2017
  84. 08/27 attr.c: tighten constness around "git_attr" structureBrandon Williams, Jan 28, 2017
  85. 04/27 attr.c: explain the lack of attr-name syntax check in parse_attr()Brandon Williams, Jan 28, 2017
  86. 09/27 attr.c: plug small leak in parse_attr_line()Brandon Williams, Jan 28, 2017
  87. 10/27 attr: support quoting pathname patterns in C styleBrandon Williams, Jan 28, 2017
  88. 11/27 attr.c: add push_stack() helperBrandon Williams, Jan 28, 2017
  89. 12/27 Documentation: fix a typoBrandon Williams, Jan 28, 2017
  90. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 28, 2017
  91. 15/27 attr: (re)introduce git_check_attr() and struct attr_checkBrandon Williams, Jan 30, 2017
  92. 13/27 attr.c: outline the future plans by heavily commentingBrandon Williams, Jan 28, 2017
  93. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 28, 2017
  94. Stefan BellerJan 28, 2017
  95. Brandon WilliamsJan 29, 2017
  96. 16/27 attr: convert git_all_attrs() to use "struct attr_check"Brandon Williams, Jan 30, 2017
  97. 14/27 attr: rename function and struct related to checking attributesBrandon Williams, Jan 28, 2017
  98. 18/27 attr: retire git_check_attrs() APIBrandon Williams, Jan 28, 2017
  99. 19/27 attr: pass struct attr_check to collect_some_attrsBrandon Williams, Jan 28, 2017
  100. 17/27 attr: convert git_check_attrs() callers to use the new APIBrandon Williams, Jan 28, 2017
  101. 22/27 attr: eliminate global check_all_attr arrayBrandon Williams, Jan 28, 2017
  102. 21/27 attr: use hashmap for attribute dictionaryBrandon Williams, Jan 28, 2017
  103. 26/27 attr: push the bare repo check into read_attr()Brandon Williams, Jan 28, 2017
  104. 25/27 attr: store attribute stack in attr_check structureBrandon Williams, Jan 28, 2017
  105. 20/27 attr: change validity check for attribute names to use positive logicBrandon Williams, Jan 28, 2017
  106. 24/27 attr: tighten const correctness with git_attr and match_attrBrandon Williams, Jan 28, 2017
  107. 27/27 attr: reformat git_attr_set_direction() functionBrandon Williams, Jan 28, 2017
  108. 23/27 attr: remove maybe-real, maybe-macro from git_attrBrandon Williams, Jan 28, 2017
  109. Junio C HamanoFeb 2, 2017
  110. Brandon WilliamsFeb 9, 2017
  111. Junio C HamanoFeb 9, 2017

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.