ui-repolist: implement lazy caching of repo->mtime

When sorting the list of repositories by their last modification time,
cgit would (in the worst case) invoke fstat(3) four times and open(3)
twice for each callback from qsort(3). This obviously scales very badly.

Now, the calculated modtime for each repo is saved in repo->mtime, thus
keeping the number of stat/open invocations identical for sorted and
unsorted repo-listings.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
This commit is contained in:
Lars Hjemli 2008-11-29 16:46:37 +01:00
szülő 54272e6096
commit 8813170390
3 fájl változott, egészen pontosan 14 új sor hozzáadva és 4 régi sor törölve

1
cgit.h
Fájl megtekintése

@ -61,6 +61,7 @@ struct cgit_repo {
int snapshots; int snapshots;
int enable_log_filecount; int enable_log_filecount;
int enable_log_linecount; int enable_log_linecount;
time_t mtime;
}; };
struct cgit_repolist { struct cgit_repolist {

Fájl megtekintése

@ -60,6 +60,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
ret->enable_log_linecount = ctx.cfg.enable_log_linecount; ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
ret->module_link = ctx.cfg.module_link; ret->module_link = ctx.cfg.module_link;
ret->readme = NULL; ret->readme = NULL;
ret->mtime = -1;
return ret; return ret;
} }

Fájl megtekintése

@ -32,19 +32,27 @@ static int get_repo_modtime(const struct cgit_repo *repo, time_t *mtime)
{ {
char *path; char *path;
struct stat s; struct stat s;
struct cgit_repo *r = (struct cgit_repo *)repo;
if (repo->mtime != -1) {
*mtime = repo->mtime;
return 1;
}
path = fmt("%s/%s", repo->path, ctx.cfg.agefile); path = fmt("%s/%s", repo->path, ctx.cfg.agefile);
if (stat(path, &s) == 0) { if (stat(path, &s) == 0) {
*mtime = read_agefile(path); *mtime = read_agefile(path);
r->mtime = *mtime;
return 1; return 1;
} }
path = fmt("%s/refs/heads/%s", repo->path, repo->defbranch); path = fmt("%s/refs/heads/%s", repo->path, repo->defbranch);
if (stat(path, &s) == 0) { if (stat(path, &s) == 0)
*mtime = s.st_mtime; *mtime = s.st_mtime;
return 1; else
} *mtime = 0;
return 0;
r->mtime = *mtime;
return (r->mtime != 0);
} }
static void print_modtime(struct cgit_repo *repo) static void print_modtime(struct cgit_repo *repo)