2 * Copyright (C) 2002-2006 Andrew Tridgell
3 * Copyright (C) 2009-2016 Joel Rosdahl
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 3 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * When "max files" or "max cache size" is reached, one of the 16 cache
24 * subdirectories is cleaned up. When doing so, files are deleted (in LRU
25 * order) until the levels are below LIMIT_MULTIPLE.
27 #define LIMIT_MULTIPLE 0.8
34 static unsigned allocated; /* Size of the files array. */
35 static unsigned num_files; /* Number of used entries in the files array. */
37 static uint64_t cache_size;
38 static size_t files_in_cache;
39 static uint64_t cache_size_threshold;
40 static size_t files_in_cache_threshold;
42 /* File comparison function that orders files in mtime order, oldest first. */
44 files_compare(struct files **f1, struct files **f2)
46 if ((*f2)->mtime == (*f1)->mtime) {
47 return strcmp((*f1)->fname, (*f2)->fname);
49 if ((*f2)->mtime > (*f1)->mtime) {
55 /* this builds the list of files in the cache */
57 traverse_fn(const char *fname, struct stat *st)
61 if (!S_ISREG(st->st_mode)) {
66 if (str_eq(p, "stats")) {
70 if (str_startswith(p, ".nfs")) {
71 /* Ignore temporary NFS files that may be left for open but deleted
76 if (strstr(p, ".tmp.")) {
77 /* delete any tmp files older than 1 hour */
78 if (st->st_mtime + 3600 < time(NULL)) {
84 if (strstr(p, "CACHEDIR.TAG")) {
88 if (num_files == allocated) {
89 allocated = 10000 + num_files*2;
90 files = (struct files **)x_realloc(files, sizeof(struct files *)*allocated);
93 files[num_files] = (struct files *)x_malloc(sizeof(struct files));
94 files[num_files]->fname = x_strdup(fname);
95 files[num_files]->mtime = st->st_mtime;
96 files[num_files]->size = file_size(st);
97 cache_size += files[num_files]->size;
106 delete_file(const char *path, size_t size)
108 if (x_unlink(path) == 0) {
111 } else if (errno != ENOENT && errno != ESTALE) {
112 cc_log("Failed to unlink %s (%s)", path, strerror(errno));
117 delete_sibling_file(const char *base, const char *extension)
122 path = format("%s%s", base, extension);
123 if (lstat(path, &st) == 0) {
124 delete_file(path, file_size(&st));
125 } else if (errno != ENOENT && errno != ESTALE) {
126 cc_log("Failed to stat %s: %s", path, strerror(errno));
131 /* sort the files we've found and delete the oldest ones until we are
132 below the thresholds */
137 char *last_base = x_strdup("");
140 /* Sort in ascending mtime order. */
141 qsort(files, num_files, sizeof(struct files *), (COMPAR_FN_T)files_compare);
144 /* delete enough files to bring us below the threshold */
145 for (i = 0; i < num_files; i++) {
148 if ((cache_size_threshold == 0
149 || cache_size <= cache_size_threshold)
150 && (files_in_cache_threshold == 0
151 || files_in_cache <= files_in_cache_threshold)) {
155 ext = get_extension(files[i]->fname);
156 if (str_eq(ext, ".o")
158 || str_eq(ext, ".gcno")
159 || str_eq(ext, ".dia")
160 || str_eq(ext, ".stderr")
161 || str_eq(ext, "")) {
162 char *base = remove_extension(files[i]->fname);
163 if (!str_eq(base, last_base)) { /* Avoid redundant unlinks. */
165 * Make sure that all sibling files are deleted so that a cached result
166 * is removed completely. Note the order of deletions -- the stderr
167 * file must be deleted last because if the ccache process gets killed
168 * after deleting the .stderr but before deleting the .o, the cached
169 * result would be inconsistent.
171 delete_sibling_file(base, ".o");
172 delete_sibling_file(base, ".d");
173 delete_sibling_file(base, ".gcno");
174 delete_sibling_file(base, ".dia");
175 delete_sibling_file(base, ".stderr");
176 delete_sibling_file(base, ""); /* Object file from ccache 2.4. */
181 /* .manifest or unknown file. */
182 delete_file(files[i]->fname, files[i]->size);
188 /* cleanup in one cache subdir */
190 cleanup_dir(struct conf *conf, const char *dir)
194 cc_log("Cleaning up cache directory %s", dir);
196 cache_size_threshold = conf->max_size * LIMIT_MULTIPLE / 16;
197 files_in_cache_threshold = conf->max_files * LIMIT_MULTIPLE / 16;
203 /* build a list of files */
204 traverse(dir, traverse_fn);
206 /* clean the cache */
209 stats_set_sizes(dir, files_in_cache, cache_size);
212 for (i = 0; i < num_files; i++) {
213 free(files[i]->fname);
228 /* cleanup in all cache subdirs */
229 void cleanup_all(struct conf *conf)
233 for (i = 0; i <= 0xF; i++) {
234 char *dname = format("%s/%1x", conf->cache_dir, i);
235 cleanup_dir(conf, dname);
240 /* traverse function for wiping files */
241 static void wipe_fn(const char *fname, struct stat *st)
245 if (!S_ISREG(st->st_mode)) {
250 if (str_eq(p, "stats")) {
259 /* wipe all cached files in all subdirs */
260 void wipe_all(struct conf *conf)
264 for (i = 0; i <= 0xF; i++) {
265 char *dname = format("%s/%1x", conf->cache_dir, i);
266 traverse(dname, wipe_fn);
270 /* and fix the counters */