From 2c70e914664e5afda521d306524d4e6869b57001 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 8 Aug 2026 12:50:08 -1000 Subject: Stop the index and the log repeating work --- source/ui-repolist.c | 55 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'source/ui-repolist.c') diff --git a/source/ui-repolist.c b/source/ui-repolist.c index e18e46e..e2c4abf 100644 --- a/source/ui-repolist.c +++ b/source/ui-repolist.c @@ -151,9 +151,11 @@ static int any_repos_visible(void) return 0; } -static void print_sort_header(const char *title, const char *sort) +// The index url is the same for every heading and every row, so the caller +// works it out once rather than building and freeing one per cell. +static void print_sort_header(const char *title, const char *sort, + const char *currenturl) { - char *currenturl = cgit_currenturl(); htmlf("%s", title); - free(currenturl); } -static void print_header(void) +static void print_header(const char *currenturl) { html(""); - print_sort_header("Name", "name"); - print_sort_header("Description", "desc"); + print_sort_header("Name", "name", currenturl); + print_sort_header("Description", "desc", currenturl); if (ctx.cfg.enable_index_owner) - print_sort_header("Owner", "owner"); - print_sort_header("Idle", "idle"); + print_sort_header("Owner", "owner", currenturl); + print_sort_header("Idle", "idle", currenturl); if (ctx.cfg.enable_index_links) html("Links"); html("\n"); @@ -233,6 +234,19 @@ static int sort_owner(const void *a, const void *b) return cmp(r1->owner, r2->owner); } +/* Resolve every repository's modification time up front. get_repo_modtime + * caches into the repo it is given, but qsort moves those structs around while + * it sorts, so a comparator that fills the cache loses most of what it stored + * and stats the same repository again and again. */ +static void resolve_modtimes(void) +{ + time_t t; + int i; + + for (i = 0; i < cgit_repolist.count; i++) + get_repo_modtime(&cgit_repolist.repos[i], &t); +} + static int sort_idle(const void *a, const void *b) { const struct cgit_repo *r1 = a; @@ -288,6 +302,8 @@ static int sort_repolist(char *field) for (column = &sortcolumn[0]; column->name; column++) { if (strcmp(field, column->name)) continue; + if (column->fn == sort_idle || column->fn == sort_section) + resolve_modtimes(); qsort(cgit_repolist.repos, cgit_repolist.count, sizeof(struct cgit_repo), column->fn); return 1; @@ -302,6 +318,7 @@ void cgit_print_repolist(void) char *last_section = NULL; char *section; char *repourl; + char *currenturl; int sorted = 0; if (!any_repos_visible()) { @@ -324,6 +341,7 @@ void cgit_print_repolist(void) else if (ctx.cfg.section_sort) sort_repolist("section"); + currenturl = cgit_currenturl(); html(""); for (i = 0; i < cgit_repolist.count; i++) { ctx.repo = &cgit_repolist.repos[i]; @@ -335,7 +353,7 @@ void cgit_print_repolist(void) if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) continue; if (!header++) - print_header(); + print_header(currenturl); section = ctx.repo->section; if (section && !strcmp(section, "")) section = NULL; @@ -363,17 +381,13 @@ void cgit_print_repolist(void) html(""); if (ctx.cfg.enable_index_owner) { html(""); } html("
"); - { - char *currenturl = cgit_currenturl(); - html(""); - html_txt(ctx.repo->owner); - html(""); - free(currenturl); - } + html(""); + html_txt(ctx.repo->owner); + html(""); html(""); @@ -392,6 +406,7 @@ void cgit_print_repolist(void) html("
"); if (hits > ctx.cfg.max_repo_count) print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search, ctx.qry.sort); + free(currenturl); cgit_print_docend(); } -- cgit v2.8.0