Making a single preparation run for counting the lines will avoid memory fragmentation. Also, fix the allocated memory size which was wrong when sizeof(int *) != sizeof(int), and would have been too small for sizeof(int *) < sizeof(int), admittedly unlikely. Signed-off-by: David Kastrup <dak@xxxxxxx> --- Now without including git-compat-util.h (included by cache.h already). builtin/blame.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index e44a6bb..59d62dc 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1772,25 +1772,38 @@ static int prepare_lines(struct scoreboard *sb) { const char *buf = sb->final_buf; unsigned long len = sb->final_buf_size; - int num = 0, incomplete = 0, bol = 1; + const char *end = buf + len; + const char *p; + int *lineno; + int num = 0, incomplete = 0; - if (len && buf[len-1] != '\n') - incomplete++; /* incomplete line at the end */ - while (len--) { - if (bol) { - sb->lineno = xrealloc(sb->lineno, - sizeof(int *) * (num + 1)); - sb->lineno[num] = buf - sb->final_buf; - bol = 0; + for (p = buf;; num++) { + p = memchr(p, '\n', end - p); + if (p) { + p++; + continue; } - if (*buf++ == '\n') { - num++; - bol = 1; + break; + } + + if (len && end[-1] != '\n') + incomplete++; /* incomplete line at the end */ + + sb->lineno = lineno = xmalloc(sizeof(int) * (num + incomplete + 1)); + + for (p = buf;;) { + *lineno++ = p - buf; + p = memchr(p, '\n', end - p); + if (p) { + p++; + continue; } + break; } - sb->lineno = xrealloc(sb->lineno, - sizeof(int *) * (num + incomplete + 1)); - sb->lineno[num + incomplete] = buf - sb->final_buf; + + if (incomplete) + *lineno++ = len; + sb->num_lines = num + incomplete; return sb->num_lines; } -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html