diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Stop the index and the log repeating work
Diffstat (limited to 'source')
-rw-r--r--source/parsing.c10
-rw-r--r--source/ui-repolist.c55
2 files changed, 43 insertions, 22 deletions
diff --git a/source/parsing.c b/source/parsing.c
index f6b1a02..0d63b51 100644
--- a/source/parsing.c
+++ b/source/parsing.c
@@ -62,12 +62,18 @@ void cgit_parse_url(const char *url)
static char *substr(const char *head, const char *tail)
{
+ size_t len;
char *buf;
if (tail < head)
return xstrdup("");
- buf = xmalloc(tail - head + 1);
- strlcpy(buf, head, tail - head + 1);
+ // head points into the commit buffer, so strlcpy would measure the
+ // whole remaining commit just to copy a name or a subject off the front
+ // of it.
+ len = tail - head;
+ buf = xmalloc(len + 1);
+ memcpy(buf, head, len);
+ buf[len] = '\0';
return buf;
}
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("<th class='left col-%s'><a href='", sort);
html_attr(currenturl);
htmlf("?s=%s", sort);
@@ -162,17 +164,16 @@ static void print_sort_header(const char *title, const char *sort)
html_url_arg(ctx.qry.search);
}
htmlf("'>%s</a></th>", title);
- free(currenturl);
}
-static void print_header(void)
+static void print_header(const char *currenturl)
{
html("<tr class='nohover'>");
- 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("<th class='left col-links'>Links</th>");
html("</tr>\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("<table class='list nowrap repolist'>");
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("</td>");
if (ctx.cfg.enable_index_owner) {
html("<td class='col-owner'>");
- {
- char *currenturl = cgit_currenturl();
- html("<a href='");
- html_attr(currenturl);
- html("?q=");
- html_url_arg(ctx.repo->owner);
- html("'>");
- html_txt(ctx.repo->owner);
- html("</a>");
- free(currenturl);
- }
+ html("<a href='");
+ html_attr(currenturl);
+ html("?q=");
+ html_url_arg(ctx.repo->owner);
+ html("'>");
+ html_txt(ctx.repo->owner);
+ html("</a>");
html("</td>");
}
html("<td class='col-idle'>");
@@ -392,6 +406,7 @@ void cgit_print_repolist(void)
html("</table>");
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();
}