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 <d...@gnu.org>
---
 builtin/blame.c | 40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index e44a6bb..522986d 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1772,25 +1772,33 @@ 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;
+
+       for (p = buf;;) {
+               if ((p = memchr(p, '\n', end-p)) == NULL)
+                       break;
+               ++num, ++p;
+       }
 
-       if (len && buf[len-1] != '\n')
+       if (len && end[-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;
-               }
-               if (*buf++ == '\n') {
-                       num++;
-                       bol = 1;
-               }
+
+       sb->lineno = lineno = xmalloc(sizeof(int) * (num + incomplete + 1));
+
+       for (p = buf;;) {
+               *lineno++ = p-buf;
+               if ((p = memchr(p, '\n', end-p)) == NULL)
+                       break;
+               ++p;
        }
-       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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to