diff --git a/CCache/ccache.h b/CCache/ccache.h index 668ce8288..3c3e22311 100644 --- a/CCache/ccache.h +++ b/CCache/ccache.h @@ -159,7 +159,7 @@ int asprintf(char **ptr, const char *format, ...); int snprintf(char *,size_t ,const char *, ...); #endif -void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize); +void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize, size_t minfiles); void cleanup_all(const char *dir); void wipe_all(const char *dir); diff --git a/CCache/cleanup.c b/CCache/cleanup.c index 99312283e..f54ee54d9 100644 --- a/CCache/cleanup.c +++ b/CCache/cleanup.c @@ -75,21 +75,40 @@ static void traverse_fn(const char *fname, struct stat *st) /* sort the files we've found and delete the oldest ones until we are below the thresholds */ -static void sort_and_clean(void) +static void sort_and_clean(size_t minfiles) { unsigned i; + size_t adjusted_minfiles = minfiles; if (num_files > 1) { /* sort in ascending data order */ qsort(files, num_files, sizeof(struct files *), (COMPAR_FN_T)files_compare); } + /* ensure newly cached files (minfiles) are kept - instead of matching + the filenames of those newly cached, a faster and simpler approach + assumes these are the most recent in the cache and if any other + cached files have an identical time stamp, they will also be kept - + this approach would not be needed if the cleanup was done at exit. */ + if (minfiles != 0 && minfiles < num_files) { + unsigned minfiles_index = num_files - minfiles; + time_t minfiles_time = files[minfiles_index]->mtime; + for (i=1; i<=minfiles_index; i++) { + if (files[minfiles_index-i]->mtime == minfiles_time) + adjusted_minfiles++; + else + break; + } + } /* delete enough files to bring us below the threshold */ for (i=0;ifname) != 0 && errno != ENOENT) { fprintf(stderr, "unlink %s - %s\n", files[i]->fname, strerror(errno)); @@ -103,7 +122,7 @@ static void sort_and_clean(void) } /* cleanup in one cache subdir */ -void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize) +void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize, size_t minfiles) { unsigned i; @@ -117,7 +136,7 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize) traverse(dir, traverse_fn); /* clean the cache */ - sort_and_clean(); + sort_and_clean(minfiles); stats_set_sizes(dir, total_files, total_size); @@ -151,7 +170,8 @@ void cleanup_all(const char *dir) cleanup_dir(dname, counters[STATS_MAXFILES], - counters[STATS_MAXSIZE]); + counters[STATS_MAXSIZE], + 0); free(dname); free(sfile); } diff --git a/CCache/stats.c b/CCache/stats.c index 92bc4a835..d2122bcd3 100644 --- a/CCache/stats.c +++ b/CCache/stats.c @@ -168,7 +168,8 @@ static void stats_update_size(enum stats stat, size_t size, size_t numfiles) if (need_cleanup) { char *p = dirname(stats_file); - cleanup_dir(p, counters[STATS_MAXFILES], counters[STATS_MAXSIZE]); + cleanup_dir(p, counters[STATS_MAXFILES], counters[STATS_MAXSIZE], + numfiles); free(p); } }