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

[PATCH] blame.c: prepare_lines should not call xrealloc for every line

From
David Kastrup <dak@gnu.org>
Date
Feb 4, 2014, 20:06 UTC
Message-ID
<1391544367-14599-1-git-send-email-dak@gnu.org>

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@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
Next: David Kastrup
Message 1 of 23 in “blame.c: prepare_lines should not call xrealloc for every line”
  1. blame.c: prepare_lines should not call xrealloc for every lineDavid Kastrup, Feb 4, 2014
  2. David KastrupFeb 4, 2014
  3. Junio C HamanoFeb 4, 2014
  4. Junio C HamanoFeb 4, 2014
  5. David KastrupFeb 4, 2014
  6. Philip OakleyFeb 4, 2014
  7. Philip OakleyFeb 4, 2014
  8. Junio C HamanoFeb 4, 2014
  9. David KastrupFeb 4, 2014
  10. Junio C HamanoFeb 4, 2014
  11. David KastrupFeb 4, 2014
  12. Junio C HamanoFeb 4, 2014
  13. David KastrupFeb 4, 2014
  14. Junio C HamanoFeb 4, 2014
  15. David KastrupFeb 4, 2014
  16. Junio C HamanoFeb 4, 2014
  17. David KastrupFeb 5, 2014
  18. Junio C HamanoFeb 5, 2014
  19. David KastrupFeb 6, 2014
  20. David KastrupFeb 6, 2014
  21. David KastrupFeb 5, 2014
  22. Junio C HamanoFeb 5, 2014
  23. David KastrupFeb 5, 2014

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.