{"thread":{"id":"42880","subject":"[PATCH] use strbuf_addbuf() for appending a strbuf to another","startedAt":"2016-07-19T18:36:55Z","lastAt":"2016-07-22T16:22:28Z","messageCount":5,"participants":["René Scharfe","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"291745","messageId":"578E732D.2090803@web.de","threadId":"42880","inReplyTo":null,"subject":"[PATCH] use strbuf_addbuf() for appending a strbuf to another","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2016-07-19T18:36:29Z","receivedAt":"2016-07-19T18:36:55Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Use strbuf_addbuf() where possible; it's shorter and more efficient.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n dir.c       | 2 +-\n path.c      | 2 +-\n wt-status.c | 2 +-\n 3 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 6172b34..0ea235f 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -2364,7 +2364,7 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra\n \n \tvarint_len = encode_varint(untracked->ident.len, varbuf);\n \tstrbuf_add(out, varbuf, varint_len);\n-\tstrbuf_add(out, untracked->ident.buf, untracked->ident.len);\n+\tstrbuf_addbuf(out, &untracked->ident);\n \n \tstrbuf_add(out, ouc, ouc_size(len));\n \tfree(ouc);\ndiff --git a/path.c b/path.c\nindex 259aeed..17551c4 100644\n--- a/path.c\n+++ b/path.c\n@@ -483,7 +483,7 @@ static void do_submodule_path(struct strbuf *buf, const char *path,\n \t\tstrbuf_addstr(buf, git_dir);\n \t}\n \tstrbuf_addch(buf, '/');\n-\tstrbuf_addstr(&git_submodule_dir, buf->buf);\n+\tstrbuf_addbuf(&git_submodule_dir, buf);\n \n \tstrbuf_vaddf(buf, fmt, args);\n \ndiff --git a/wt-status.c b/wt-status.c\nindex c19b52c..dbdb543 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1062,7 +1062,7 @@ static void abbrev_sha1_in_line(struct strbuf *line)\n \t\t\tstrbuf_addf(split[1], \"%s \", abbrev);\n \t\t\tstrbuf_reset(line);\n \t\t\tfor (i = 0; split[i]; i++)\n-\t\t\t\tstrbuf_addf(line, \"%s\", split[i]->buf);\n+\t\t\t\tstrbuf_addbuf(line, split[i]);\n \t\t}\n \t}\n \tstrbuf_list_free(split);\n-- \n2.9.2\n\n"},{"id":"291804","messageId":"20160720132025.GD17469@sigill.intra.peff.net","threadId":"42880","inReplyTo":"578E732D.2090803@web.de","subject":"Re: [PATCH] use strbuf_addbuf() for appending a strbuf to another","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-20T13:20:25Z","receivedAt":"2016-07-20T13:20:41Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jul 19, 2016 at 08:36:29PM +0200, René Scharfe wrote:\n\n> Use strbuf_addbuf() where possible; it's shorter and more efficient.\n\nAfter seeing \"efficient\", I was momentarily surprised by the first hunk:\n\n> diff --git a/dir.c b/dir.c\n> index 6172b34..0ea235f 100644\n> --- a/dir.c\n> +++ b/dir.c\n> @@ -2364,7 +2364,7 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra\n>  \n>  \tvarint_len = encode_varint(untracked->ident.len, varbuf);\n>  \tstrbuf_add(out, varbuf, varint_len);\n> -\tstrbuf_add(out, untracked->ident.buf, untracked->ident.len);\n> +\tstrbuf_addbuf(out, &untracked->ident);\n\nThis is actually slightly _less_ efficient, because we already are using\nthe precomputed len, and the new code will call an extra strbuf_grow()\nto cover the case where the two arguments are the same.  See 81d2cae\n(strbuf_addbuf(): allow passing the same buf to dst and src,\n2010-01-12).\n\nBut it almost certainly doesn't matter, and it definitely _is_ an\nimprovement for the other \"addstr\" cases, which are doing an unncessary\nstrlen().\n\nAnd anyway the readability improvement trumps all of that in my mind. So\nI think overall it is a nice cleanup; I'm mostly just commenting for the\nsake of other reviewers.\n\n-Peff\n"},{"id":"291926","messageId":"5790FC74.6000602@web.de","threadId":"42880","inReplyTo":"20160720132025.GD17469@sigill.intra.peff.net","subject":"Re: [PATCH] use strbuf_addbuf() for appending a strbuf to another","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2016-07-21T16:46:44Z","receivedAt":"2016-07-21T16:47:14Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 20.07.2016 um 15:20 schrieb Jeff King:\n> On Tue, Jul 19, 2016 at 08:36:29PM +0200, René Scharfe wrote:\n> \n>> Use strbuf_addbuf() where possible; it's shorter and more efficient.\n> \n> After seeing \"efficient\", I was momentarily surprised by the first hunk:\n> \n>> diff --git a/dir.c b/dir.c\n>> index 6172b34..0ea235f 100644\n>> --- a/dir.c\n>> +++ b/dir.c\n>> @@ -2364,7 +2364,7 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra\n>>   \n>>   \tvarint_len = encode_varint(untracked->ident.len, varbuf);\n>>   \tstrbuf_add(out, varbuf, varint_len);\n>> -\tstrbuf_add(out, untracked->ident.buf, untracked->ident.len);\n>> +\tstrbuf_addbuf(out, &untracked->ident);\n> \n> This is actually slightly _less_ efficient, because we already are using\n> the precomputed len, and the new code will call an extra strbuf_grow()\n> to cover the case where the two arguments are the same.  See 81d2cae\n> (strbuf_addbuf(): allow passing the same buf to dst and src,\n> 2010-01-12).\n\nAh, I wasn't aware of that.  Calling strbuf_grow() twice shouldn't be\nthaaat bad.  However, I wonder where we duplicate strbufs, or why we\nwould ever want to do so.  Anyway, here's a patch for that:\n\n-- >8 --\nSubject: strbuf: avoid calling strbuf_grow() twice in strbuf_addbuf()\n\nImplement strbuf_addbuf() as a normal function in order to avoid calling\nstrbuf_grow() twice, with the second callinside strbud_add() being a\nno-op.  This is slightly faster and also reduces the text size a bit.\n\nSigned-off-by: Rene Scharfe <l.s.r@web.de>\n---\n strbuf.c | 7 +++++++\n strbuf.h | 6 +-----\n 2 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/strbuf.c b/strbuf.c\nindex 1ba600b..f3bd571 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -197,6 +197,13 @@ void strbuf_add(struct strbuf *sb, const void *data, size_t len)\n \tstrbuf_setlen(sb, sb->len + len);\n }\n \n+void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)\n+{\n+\tstrbuf_grow(sb, sb2->len);\n+\tmemcpy(sb->buf + sb->len, sb2->buf, sb2->len);\n+\tstrbuf_setlen(sb, sb->len + sb2->len);\n+}\n+\n void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)\n {\n \tstrbuf_grow(sb, len);\ndiff --git a/strbuf.h b/strbuf.h\nindex 83c5c98..ba8d5f1 100644\n--- a/strbuf.h\n+++ b/strbuf.h\n@@ -263,11 +263,7 @@ static inline void strbuf_addstr(struct strbuf *sb, const char *s)\n /**\n  * Copy the contents of another buffer at the end of the current one.\n  */\n-static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2)\n-{\n-\tstrbuf_grow(sb, sb2->len);\n-\tstrbuf_add(sb, sb2->buf, sb2->len);\n-}\n+extern void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2);\n \n /**\n  * Copy part of the buffer from a given position till a given length to the\n-- \n2.9.2\n\n"},{"id":"291936","messageId":"20160721210253.GA4604@sigill.intra.peff.net","threadId":"42880","inReplyTo":"5790FC74.6000602@web.de","subject":"Re: [PATCH] use strbuf_addbuf() for appending a strbuf to another","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-07-21T21:02:54Z","receivedAt":"2016-07-21T21:03:13Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 21, 2016 at 06:46:44PM +0200, René Scharfe wrote:\n\n> >> -\tstrbuf_add(out, untracked->ident.buf, untracked->ident.len);\n> >> +\tstrbuf_addbuf(out, &untracked->ident);\n> > \n> > This is actually slightly _less_ efficient, because we already are using\n> > the precomputed len, and the new code will call an extra strbuf_grow()\n> > to cover the case where the two arguments are the same.  See 81d2cae\n> > (strbuf_addbuf(): allow passing the same buf to dst and src,\n> > 2010-01-12).\n> \n> Ah, I wasn't aware of that.  Calling strbuf_grow() twice shouldn't be\n> thaaat bad.  However, I wonder where we duplicate strbufs, or why we\n> would ever want to do so.  Anyway, here's a patch for that:\n\nI don't think we do. Going back to the original discussion:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/136141/focus=136774\n\nit was mostly just \"hey, this would fail really confusingly if we ever\ndid, so let's make it safe\".\n\nThe second strbuf_grow() is by definition a noop (which is why 81d2cae\nworks at all), but we do pay the size-computation cost.\n\n> -- >8 --\n> Subject: strbuf: avoid calling strbuf_grow() twice in strbuf_addbuf()\n> \n> Implement strbuf_addbuf() as a normal function in order to avoid calling\n> strbuf_grow() twice, with the second callinside strbud_add() being a\n> no-op.  This is slightly faster and also reduces the text size a bit.\n\nSeems reasonable.  IMHO the main advantage is that one does not have to\nreason about the double strbuf_grow() (i.e., that the strbuf_add() is\nsafe because we know its grow is a noop).\n\n-Peff\n"},{"id":"291970","messageId":"xmqqr3albq2s.fsf@gitster.mtv.corp.google.com","threadId":"42880","inReplyTo":"20160721210253.GA4604@sigill.intra.peff.net","subject":"Re: [PATCH] use strbuf_addbuf() for appending a strbuf to another","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-07-22T16:22:19Z","receivedAt":"2016-07-22T16:22:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I don't think we do. Going back to the original discussion:\n>\n>   http://thread.gmane.org/gmane.comp.version-control.git/136141/focus=136774\n>\n> it was mostly just \"hey, this would fail really confusingly if we ever\n> did, so let's make it safe\".\n>\n> The second strbuf_grow() is by definition a noop (which is why 81d2cae\n> works at all), but we do pay the size-computation cost.\n\nBoth true.  If the second one is not a noop, nothing is fixed by\n81d2cae at all, but it is subtle.\n\nRené's update makes it far easier to understand what is going on.\n\n>> -- >8 --\n>> Subject: strbuf: avoid calling strbuf_grow() twice in strbuf_addbuf()\n>> \n>> Implement strbuf_addbuf() as a normal function in order to avoid calling\n>> strbuf_grow() twice, with the second callinside strbud_add() being a\n>> no-op.  This is slightly faster and also reduces the text size a bit.\n>\n> Seems reasonable.  IMHO the main advantage is that one does not have to\n> reason about the double strbuf_grow() (i.e., that the strbuf_add() is\n> safe because we know its grow is a noop).\n>\n> -Peff\n"}]}