git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: Eric Sunshine <sunshine@sunshineco.com>
Cc: "H.Merijn Brand" <h.m.brand@xs4all.nl>, git@vger.kernel.org
Subject: Re: [PATCH 3/3] introduce "format" date-mode
Date: Tue, 30 Jun 2015 06:20:56 -0400	[thread overview]
Message-ID: <20150630102055.GA11928@peff.net> (raw)
In-Reply-To: <20150629222247.GA31607@flurp.local>

On Mon, Jun 29, 2015 at 06:22:47PM -0400, Eric Sunshine wrote:

> Clients of strbuf rightly expect the buffer to grow as needed in
> order to complete the requested operation. It is, therefore, both
> weird and expectation-breaking for strbuf_addftime() to lack this
> behavior. Worse, it doesn't even signal when the format has failed
> due to insufficient buffer space.

Agreed on all points.

> --- 8< ---
> void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm)
> {
> 	size_t len;
> 	struct strbuf f = STRBUF_INIT;
> 
> 	/*
> 	 * This is a bit tricky since strftime returns 0 if the result did not
> 	 * fit in the supplied buffer, as well as when the formatted time has
> 	 * zero length. In the former case, we need to grow the buffer and try
> 	 * again. To distinguish between the two cases, we supply strftime with
> 	 * a format string one character longer than what the client supplied,
> 	 * which ensures that a successful format will have non-zero length,
> 	 * and then drop the extra character from the formatted time before
> 	 * returning.
> 	 */
> 	strbuf_addf(&f, "%s ", fmt);

Basically I was trying to avoid making any assumptions about exactly how
strftime works. But presumably "stick a space in the format" is a
universally reasonable thing to do. It's a hack, but it's contained to
the function.

> 	do {
> 		strbuf_grow(sb, 128);
> 		len = strftime(sb->buf + sb->len, sb->alloc - sb->len,
> 			       f.buf, tm);
> 	} while (!len);

I think we need to keep growing this 128 ourselves, or else each loop
iteration will just say "yup, we have 128 bytes available; no need to
grow".


> [...]
> 
> If this is performance critical code, then the augmented format
> string can be constructed with less expensive functions than
> strbuf_addf().

This does get called a lot (e.g., once per commit). One extra allocation
would probably not kill us there, but I think we could fairly trivially
put this on the unlikely path:

  size_t hint = 128;
  size_t len;

  /* optimize out obvious 0-length case */
  if (!*fmt)
	return;

  strbuf_grow(sb, hint);
  len = strftime(sb->buf + sb->len, sb->alloc - sb->len, fmt, tm);

  /* maybe not enough room, or maybe 0-length output */
  if (!len) {
	struct strbuf f = STRBUF_INIT;
	strbuf_addf(&f, "%s ", fmt);
	while (!len) {
		hint *= 2;
		strbuf_grow(sb, hint);
		len = strftime(sb->buf + sb->len, sb->alloc - sb->len, f.buf, tm);
	}
  }

I'd guess most cases will fit in 128 bytes and never even hit this code
path. You could also get fancier and start the buffer smaller, but only
do the fmt hack when we cross a threshold.

-Peff

  reply	other threads:[~2015-06-30 10:21 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-25 11:19 several date related issues H.Merijn Brand
2015-06-25 12:44 ` Jeff King
2015-06-25 12:56   ` H.Merijn Brand
2015-06-25 16:53     ` [PATCH 0/3] localized date format Jeff King
2015-06-25 16:54       ` [PATCH 1/3] show-branch: use DATE_RELATIVE instead of magic number Jeff King
2015-06-25 16:55       ` [PATCH 2/3] convert "enum date_mode" into a struct Jeff King
2015-06-25 17:03         ` John Keeping
2015-06-25 17:22           ` Jeff King
2015-07-07 20:37         ` Junio C Hamano
2015-07-07 20:48           ` Jeff King
2015-07-07 21:05             ` Junio C Hamano
2015-07-07 21:13               ` Jeff King
2015-07-07 21:19                 ` Junio C Hamano
2015-06-25 16:55       ` [PATCH 3/3] introduce "format" date-mode Jeff King
2015-06-29 22:22         ` Eric Sunshine
2015-06-30 10:20           ` Jeff King [this message]
2015-06-30 16:22             ` Junio C Hamano
2015-06-30 17:50               ` Jeff King
2015-06-30 19:23                 ` Junio C Hamano
2015-06-30 19:33                   ` Jeff King
2015-06-30 16:58             ` Eric Sunshine
2015-06-30 17:58               ` Jeff King
2015-06-30 18:13                 ` Eric Sunshine
2015-06-30 19:22                   ` Jeff King
2015-06-30 17:05             ` Junio C Hamano
2015-06-30 17:48               ` Eric Sunshine
2015-06-30 19:17               ` Jeff King
2015-06-30 13:26           ` Jeff King
2015-06-30 17:05             ` Eric Sunshine
2015-07-21  0:41             ` Eric Sunshine
2015-07-21  1:19               ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150630102055.GA11928@peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=h.m.brand@xs4all.nl \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).