summaryrefslogtreecommitdiffabout
path: root/shared.c
authorLars Hjemli <hjemli@gmail.com>2008-11-29 15:46:37 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-11-29 15:46:37 (UTC)
commit8813170390f3c3a0f4743afbc92ede42953fa3b0 (patch) (unidiff)
tree39305350baee1eb564aae00294634bbe544983d3 /shared.c
parent54272e60965ec6a98b49cbf67d72a4b1f5adc55b (diff)
downloadcgit-8813170390f3c3a0f4743afbc92ede42953fa3b0.zip
cgit-8813170390f3c3a0f4743afbc92ede42953fa3b0.tar.gz
cgit-8813170390f3c3a0f4743afbc92ede42953fa3b0.tar.bz2
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>
Diffstat (limited to 'shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--shared.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/shared.c b/shared.c
index f5875e4..89d1bab 100644
--- a/shared.c
+++ b/shared.c
@@ -1,158 +1,159 @@
1/* shared.c: global vars + some callback functions 1/* shared.c: global vars + some callback functions
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10 10
11struct cgit_repolist cgit_repolist; 11struct cgit_repolist cgit_repolist;
12struct cgit_context ctx; 12struct cgit_context ctx;
13int cgit_cmd; 13int cgit_cmd;
14 14
15int chk_zero(int result, char *msg) 15int chk_zero(int result, char *msg)
16{ 16{
17 if (result != 0) 17 if (result != 0)
18 die("%s: %s", msg, strerror(errno)); 18 die("%s: %s", msg, strerror(errno));
19 return result; 19 return result;
20} 20}
21 21
22int chk_positive(int result, char *msg) 22int chk_positive(int result, char *msg)
23{ 23{
24 if (result <= 0) 24 if (result <= 0)
25 die("%s: %s", msg, strerror(errno)); 25 die("%s: %s", msg, strerror(errno));
26 return result; 26 return result;
27} 27}
28 28
29int chk_non_negative(int result, char *msg) 29int chk_non_negative(int result, char *msg)
30{ 30{
31 if (result < 0) 31 if (result < 0)
32 die("%s: %s",msg, strerror(errno)); 32 die("%s: %s",msg, strerror(errno));
33 return result; 33 return result;
34} 34}
35 35
36struct cgit_repo *cgit_add_repo(const char *url) 36struct cgit_repo *cgit_add_repo(const char *url)
37{ 37{
38 struct cgit_repo *ret; 38 struct cgit_repo *ret;
39 39
40 if (++cgit_repolist.count > cgit_repolist.length) { 40 if (++cgit_repolist.count > cgit_repolist.length) {
41 if (cgit_repolist.length == 0) 41 if (cgit_repolist.length == 0)
42 cgit_repolist.length = 8; 42 cgit_repolist.length = 8;
43 else 43 else
44 cgit_repolist.length *= 2; 44 cgit_repolist.length *= 2;
45 cgit_repolist.repos = xrealloc(cgit_repolist.repos, 45 cgit_repolist.repos = xrealloc(cgit_repolist.repos,
46 cgit_repolist.length * 46 cgit_repolist.length *
47 sizeof(struct cgit_repo)); 47 sizeof(struct cgit_repo));
48 } 48 }
49 49
50 ret = &cgit_repolist.repos[cgit_repolist.count-1]; 50 ret = &cgit_repolist.repos[cgit_repolist.count-1];
51 ret->url = trim_end(url, '/'); 51 ret->url = trim_end(url, '/');
52 ret->name = ret->url; 52 ret->name = ret->url;
53 ret->path = NULL; 53 ret->path = NULL;
54 ret->desc = "[no description]"; 54 ret->desc = "[no description]";
55 ret->owner = NULL; 55 ret->owner = NULL;
56 ret->group = ctx.cfg.repo_group; 56 ret->group = ctx.cfg.repo_group;
57 ret->defbranch = "master"; 57 ret->defbranch = "master";
58 ret->snapshots = ctx.cfg.snapshots; 58 ret->snapshots = ctx.cfg.snapshots;
59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount; 59 ret->enable_log_filecount = ctx.cfg.enable_log_filecount;
60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount; 60 ret->enable_log_linecount = ctx.cfg.enable_log_linecount;
61 ret->module_link = ctx.cfg.module_link; 61 ret->module_link = ctx.cfg.module_link;
62 ret->readme = NULL; 62 ret->readme = NULL;
63 ret->mtime = -1;
63 return ret; 64 return ret;
64} 65}
65 66
66struct cgit_repo *cgit_get_repoinfo(const char *url) 67struct cgit_repo *cgit_get_repoinfo(const char *url)
67{ 68{
68 int i; 69 int i;
69 struct cgit_repo *repo; 70 struct cgit_repo *repo;
70 71
71 for (i=0; i<cgit_repolist.count; i++) { 72 for (i=0; i<cgit_repolist.count; i++) {
72 repo = &cgit_repolist.repos[i]; 73 repo = &cgit_repolist.repos[i];
73 if (!strcmp(repo->url, url)) 74 if (!strcmp(repo->url, url))
74 return repo; 75 return repo;
75 } 76 }
76 return NULL; 77 return NULL;
77} 78}
78 79
79void *cgit_free_commitinfo(struct commitinfo *info) 80void *cgit_free_commitinfo(struct commitinfo *info)
80{ 81{
81 free(info->author); 82 free(info->author);
82 free(info->author_email); 83 free(info->author_email);
83 free(info->committer); 84 free(info->committer);
84 free(info->committer_email); 85 free(info->committer_email);
85 free(info->subject); 86 free(info->subject);
86 free(info->msg); 87 free(info->msg);
87 free(info->msg_encoding); 88 free(info->msg_encoding);
88 free(info); 89 free(info);
89 return NULL; 90 return NULL;
90} 91}
91 92
92char *trim_end(const char *str, char c) 93char *trim_end(const char *str, char c)
93{ 94{
94 int len; 95 int len;
95 char *s, *t; 96 char *s, *t;
96 97
97 if (str == NULL) 98 if (str == NULL)
98 return NULL; 99 return NULL;
99 t = (char *)str; 100 t = (char *)str;
100 len = strlen(t); 101 len = strlen(t);
101 while(len > 0 && t[len - 1] == c) 102 while(len > 0 && t[len - 1] == c)
102 len--; 103 len--;
103 104
104 if (len == 0) 105 if (len == 0)
105 return NULL; 106 return NULL;
106 107
107 c = t[len]; 108 c = t[len];
108 t[len] = '\0'; 109 t[len] = '\0';
109 s = xstrdup(t); 110 s = xstrdup(t);
110 t[len] = c; 111 t[len] = c;
111 return s; 112 return s;
112} 113}
113 114
114char *strlpart(char *txt, int maxlen) 115char *strlpart(char *txt, int maxlen)
115{ 116{
116 char *result; 117 char *result;
117 118
118 if (!txt) 119 if (!txt)
119 return txt; 120 return txt;
120 121
121 if (strlen(txt) <= maxlen) 122 if (strlen(txt) <= maxlen)
122 return txt; 123 return txt;
123 result = xmalloc(maxlen + 1); 124 result = xmalloc(maxlen + 1);
124 memcpy(result, txt, maxlen - 3); 125 memcpy(result, txt, maxlen - 3);
125 result[maxlen-1] = result[maxlen-2] = result[maxlen-3] = '.'; 126 result[maxlen-1] = result[maxlen-2] = result[maxlen-3] = '.';
126 result[maxlen] = '\0'; 127 result[maxlen] = '\0';
127 return result; 128 return result;
128} 129}
129 130
130char *strrpart(char *txt, int maxlen) 131char *strrpart(char *txt, int maxlen)
131{ 132{
132 char *result; 133 char *result;
133 134
134 if (!txt) 135 if (!txt)
135 return txt; 136 return txt;
136 137
137 if (strlen(txt) <= maxlen) 138 if (strlen(txt) <= maxlen)
138 return txt; 139 return txt;
139 result = xmalloc(maxlen + 1); 140 result = xmalloc(maxlen + 1);
140 memcpy(result + 3, txt + strlen(txt) - maxlen + 4, maxlen - 3); 141 memcpy(result + 3, txt + strlen(txt) - maxlen + 4, maxlen - 3);
141 result[0] = result[1] = result[2] = '.'; 142 result[0] = result[1] = result[2] = '.';
142 return result; 143 return result;
143} 144}
144 145
145void cgit_add_ref(struct reflist *list, struct refinfo *ref) 146void cgit_add_ref(struct reflist *list, struct refinfo *ref)
146{ 147{
147 size_t size; 148 size_t size;
148 149
149 if (list->count >= list->alloc) { 150 if (list->count >= list->alloc) {
150 list->alloc += (list->alloc ? list->alloc : 4); 151 list->alloc += (list->alloc ? list->alloc : 4);
151 size = list->alloc * sizeof(struct refinfo *); 152 size = list->alloc * sizeof(struct refinfo *);
152 list->refs = xrealloc(list->refs, size); 153 list->refs = xrealloc(list->refs, size);
153 } 154 }
154 list->refs[list->count++] = ref; 155 list->refs[list->count++] = ref;
155} 156}
156 157
157struct refinfo *cgit_mk_refinfo(const char *refname, const unsigned char *sha1) 158struct refinfo *cgit_mk_refinfo(const char *refname, const unsigned char *sha1)
158{ 159{