"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
fix tog log inefficiency
To:
gameoftrees@openbsd.org
Date:
Sun, 1 Aug 2021 15:26:24 +0200

Download raw body.

Thread
  • Stefan Sperling:

    fix tog log inefficiency

The Git repository at https://github.com/adhn/nanobox-pkgsrc-lite
contains the entire git log of pkgsrc from netbsd embedded in a
single 100MB commit message.

Navigating tog's log view on this repository is rather slow because
the large message will be parsed whenever the display is refreshed.

With this patch tog log caches a copy of the first line of every
log message and uses this copy when updating the display.
This makes tog somewhat usable on the above repository.

ok?

diff aa8b5dd032c8cba930e5be67a90069a95e0001b8 /home/stsp/src/got
blob - c175ea3c10692ebe9286741d643cd9b65fb4140c
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -111,6 +111,7 @@ struct commit_queue_entry {
 	struct got_object_id *id;
 	struct got_commit_object *commit;
 	int idx;
+	char *short_message;
 };
 TAILQ_HEAD(commit_queue_head, commit_queue_entry);
 struct commit_queue {
@@ -1322,17 +1323,16 @@ format_author(wchar_t **wauthor, int *author_width, ch
 
 static const struct got_error *
 draw_commit(struct tog_view *view, struct got_commit_object *commit,
-    struct got_object_id *id, const size_t date_display_cols,
-    int author_display_cols)
+    struct got_object_id *id, const char *short_message,
+    const size_t date_display_cols, int author_display_cols)
 {
 	struct tog_log_view_state *s = &view->state.log;
 	const struct got_error *err = NULL;
 	char datebuf[12]; /* YYYY-MM-DD + SPACE + NUL */
-	char *logmsg0 = NULL, *logmsg = NULL;
 	char *author = NULL;
 	wchar_t *wlogmsg = NULL, *wauthor = NULL;
 	int author_width, logmsg_width;
-	char *newline, *line = NULL;
+	char *line = NULL;
 	int col, limit;
 	const int avail = view->ncols;
 	struct tm tm;
@@ -1405,17 +1405,8 @@ draw_commit(struct tog_view *view, struct got_commit_o
 	if (col > avail)
 		goto done;
 
-	err = got_object_commit_get_logmsg(&logmsg0, commit);
-	if (err)
-		goto done;
-	logmsg = logmsg0;
-	while (*logmsg == '\n')
-		logmsg++;
-	newline = strchr(logmsg, '\n');
-	if (newline)
-		*newline = '\0';
 	limit = avail - col;
-	err = format_line(&wlogmsg, &logmsg_width, logmsg, limit, col);
+	err = format_line(&wlogmsg, &logmsg_width, short_message, limit, col);
 	if (err)
 		goto done;
 	waddwstr(view->window, wlogmsg);
@@ -1425,7 +1416,6 @@ draw_commit(struct tog_view *view, struct got_commit_o
 		col++;
 	}
 done:
-	free(logmsg0);
 	free(wlogmsg);
 	free(author);
 	free(wauthor);
@@ -1433,19 +1423,44 @@ done:
 	return err;
 }
 
-static struct commit_queue_entry *
-alloc_commit_queue_entry(struct got_commit_object *commit,
+static const struct got_error *
+alloc_commit_queue_entry(struct commit_queue_entry **entry,
+    struct got_commit_object *commit,
     struct got_object_id *id)
 {
-	struct commit_queue_entry *entry;
+	const struct got_error *err;
+	char *logmsg0 = NULL, *logmsg = NULL;
+	char *newline;
 
-	entry = calloc(1, sizeof(*entry));
-	if (entry == NULL)
-		return NULL;
+	*entry = calloc(1, sizeof(**entry));
+	if (*entry == NULL)
+		return got_error_from_errno("calloc");
 
-	entry->id = id;
-	entry->commit = commit;
-	return entry;
+	(*entry)->id = id;
+	(*entry)->commit = commit;
+
+	err = got_object_commit_get_logmsg(&logmsg0, commit);
+	if (err)
+		goto done;
+	logmsg = logmsg0;
+	while (*logmsg == '\n')
+		logmsg++;
+	newline = strchr(logmsg, '\n');
+	if (newline)
+		*newline = '\0';
+
+	(*entry)->short_message = strdup(logmsg);
+	if ((*entry)->short_message == NULL) {
+		err = got_error_from_errno("strdup");
+		goto done;
+	}
+done:
+	free(logmsg0);
+	if (err) {
+		free(*entry);
+		*entry = NULL;
+	}
+	return err;
 }
 
 static void
@@ -1458,6 +1473,7 @@ pop_commit(struct commit_queue *commits)
 	got_object_commit_close(entry->commit);
 	commits->ncommits--;
 	/* Don't free entry->id! It is owned by the commit graph. */
+	free(entry->short_message);
 	free(entry);
 }
 
@@ -1523,11 +1539,10 @@ queue_commits(struct tog_log_thread_args *a)
 		err = got_object_open_as_commit(&commit, a->repo, id);
 		if (err)
 			break;
-		entry = alloc_commit_queue_entry(commit, id);
-		if (entry == NULL) {
-			err = got_error_from_errno("alloc_commit_queue_entry");
+	
+		err = alloc_commit_queue_entry(&entry, commit, id);
+		if (err)
 			break;
-		}
 
 		errcode = pthread_mutex_lock(&tog_mutex);
 		if (errcode) {
@@ -1715,7 +1730,7 @@ draw_commits(struct tog_view *view)
 		if (ncommits == s->selected)
 			wstandout(view->window);
 		err = draw_commit(view, entry->commit, entry->id,
-		    date_display_cols, author_cols);
+		    entry->short_message, date_display_cols, author_cols);
 		if (ncommits == s->selected)
 			wstandend(view->window);
 		if (err)