config: Use files and size limits from config

This commit is contained in:
Joel Rosdahl 2011-07-19 19:42:13 +02:00
parent 6f60433b8d
commit 7a58c8b038
7 changed files with 72 additions and 114 deletions

View File

@ -21,7 +21,6 @@
#include "ccache.h"
#include "compopt.h"
#include "conf.h"
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
@ -1775,7 +1774,7 @@ out:
}
static void
create_initial_config_file(const char *path)
create_initial_config_file(struct conf *conf, const char *path)
{
unsigned max_files, max_size;
char *stats_dir;
@ -1788,7 +1787,7 @@ create_initial_config_file(const char *path)
stats_dir = format("%s/0", conf->cache_dir);
if (stat(stats_dir, &st) == 0) {
stats_get_limits(stats_dir, &max_files, &max_size);
stats_get_obsolete_limits(stats_dir, &max_files, &max_size);
/* STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory. */
max_files *= 16;
max_size *= 16;
@ -1804,11 +1803,13 @@ create_initial_config_file(const char *path)
}
if (max_files != 0) {
fprintf(f, "max_files = %u\n", max_files);
conf->max_files = max_files;
}
if (max_size != 0) {
char *size = format_parsable_size_with_suffix(max_size);
fprintf(f, "max_size = %s\n", size);
free(size);
conf->max_size = max_size;
}
fclose(f);
}
@ -2088,6 +2089,7 @@ ccache_main_options(int argc, char *argv[])
{
int c;
size_t v;
char *errmsg;
enum longopts {
DUMP_MANIFEST
@ -2113,13 +2115,13 @@ ccache_main_options(int argc, char *argv[])
case 'c': /* --cleanup */
initialize();
cleanup_all(conf->cache_dir);
cleanup_all(conf);
printf("Cleaned cache\n");
break;
case 'C': /* --clear */
initialize();
wipe_all(conf->cache_dir);
wipe_all(conf);
printf("Cleared cache\n");
break;
@ -2130,22 +2132,23 @@ ccache_main_options(int argc, char *argv[])
case 'F': /* --max-files */
initialize();
v = atoi(optarg);
if (stats_set_limits(v, -1) == 0) {
if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
&errmsg)) {
if (v == 0) {
printf("Unset cache file limit\n");
} else {
printf("Set cache file limit to %u\n", (unsigned)v);
}
} else {
printf("Could not set cache file limit.\n");
exit(1);
fatal("could not set cache file limit: %s", errmsg);
}
break;
case 'M': /* --max-size */
initialize();
parse_size_with_suffix(optarg, &v);
if (stats_set_limits(-1, v) == 0) {
if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
&errmsg)) {
if (v == 0) {
printf("Unset cache size limit\n");
} else {
@ -2154,14 +2157,13 @@ ccache_main_options(int argc, char *argv[])
free(s);
}
} else {
printf("Could not set cache size limit.\n");
exit(1);
fatal("could not set cache size limit: %s", errmsg);
}
break;
case 's': /* --show-stats */
initialize();
stats_summary();
stats_summary(conf);
break;
case 'V': /* --version */

View File

@ -3,6 +3,7 @@
#include "system.h"
#include "mdfour.h"
#include "conf.h"
#include "counters.h"
#ifdef __GNUC__
@ -32,8 +33,8 @@ enum stats {
STATS_LINK = 10,
STATS_NUMFILES = 11,
STATS_TOTALSIZE = 12,
STATS_MAXFILES = 13,
STATS_MAXSIZE = 14,
STATS_OBSOLETE_MAXFILES = 13,
STATS_OBSOLETE_MAXSIZE = 14,
STATS_SOURCELANG = 15,
STATS_DEVICE = 16,
STATS_NOINPUT = 17,
@ -162,10 +163,10 @@ void stats_update(enum stats stat);
void stats_flush(void);
unsigned stats_get_pending(enum stats stat);
void stats_zero(void);
void stats_summary(void);
void stats_summary(struct conf *conf);
void stats_update_size(enum stats stat, size_t size, unsigned files);
void stats_get_limits(const char *dir, unsigned *maxfiles, unsigned *maxsize);
int stats_set_limits(long maxfiles, long maxsize);
void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
unsigned *maxsize);
void stats_set_sizes(const char *dir, size_t num_files, size_t total_size);
void stats_read(const char *path, struct counters *counters);
void stats_write(const char *path, struct counters *counters);
@ -186,9 +187,9 @@ void exitfn_call(void);
/* ------------------------------------------------------------------------- */
/* cleanup.c */
void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize);
void cleanup_all(const char *dir);
void wipe_all(const char *dir);
void cleanup_dir(struct conf *conf, const char *dir);
void cleanup_all(struct conf *conf);
void wipe_all(struct conf *conf);
/* ------------------------------------------------------------------------- */
/* execute.c */

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2006 Andrew Tridgell
* Copyright (C) 2009-2010 Joel Rosdahl
* Copyright (C) 2009-2011 Joel Rosdahl
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -175,14 +175,14 @@ sort_and_clean(void)
/* cleanup in one cache subdir */
void
cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
cleanup_dir(struct conf *conf, const char *dir)
{
unsigned i;
cc_log("Cleaning up cache directory %s", dir);
cache_size_threshold = maxsize * LIMIT_MULTIPLE;
files_in_cache_threshold = maxfiles * LIMIT_MULTIPLE;
cache_size_threshold = conf->max_size * LIMIT_MULTIPLE / 16;
files_in_cache_threshold = conf->max_files * LIMIT_MULTIPLE / 16;
num_files = 0;
cache_size = 0;
@ -214,16 +214,14 @@ cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
}
/* cleanup in all cache subdirs */
void cleanup_all(const char *dir)
void cleanup_all(struct conf *conf)
{
unsigned maxfiles, maxsize;
char *dname;
int i;
for (i = 0; i <= 0xF; i++) {
dname = format("%s/%1x", dir, i);
stats_get_limits(dname, &maxfiles, &maxsize);
cleanup_dir(dname, maxfiles, maxsize);
dname = format("%s/%1x", conf->cache_dir, i);
cleanup_dir(conf, dname);
free(dname);
}
}
@ -246,17 +244,17 @@ static void wipe_fn(const char *fname, struct stat *st)
}
/* wipe all cached files in all subdirs */
void wipe_all(const char *dir)
void wipe_all(struct conf *conf)
{
char *dname;
int i;
for (i = 0; i <= 0xF; i++) {
dname = format("%s/%1x", dir, i);
traverse(dir, wipe_fn);
dname = format("%s/%1x", conf->cache_dir, i);
traverse(dname, wipe_fn);
free(dname);
}
/* and fix the counters */
cleanup_all(dir);
cleanup_all(conf);
}

View File

@ -18,7 +18,6 @@
*/
#include "ccache.h"
#include "conf.h"
extern struct conf *conf;

100
stats.c
View File

@ -23,7 +23,6 @@
*/
#include "ccache.h"
#include "conf.h"
#include "hashutil.h"
#include <sys/types.h>
@ -40,13 +39,9 @@ extern unsigned lock_staleness_limit;
static struct counters *counter_updates;
/* default maximum cache size */
#ifndef DEFAULT_MAXSIZE
#define DEFAULT_MAXSIZE (1024*1024)
#endif
#define FLAG_NOZERO 1 /* don't zero with the -z option */
#define FLAG_ALWAYS 2 /* always show, even if zero */
#define FLAG_NEVER 4 /* never show */
static void display_size(size_t v);
@ -83,8 +78,8 @@ static struct {
{ STATS_BADEXTRAFILE, "error hashing extra file ", NULL, 0 },
{ STATS_NUMFILES, "files in cache ", NULL, FLAG_NOZERO|FLAG_ALWAYS },
{ STATS_TOTALSIZE, "cache size ", display_size , FLAG_NOZERO|FLAG_ALWAYS },
{ STATS_MAXFILES, "max files ", NULL, FLAG_NOZERO },
{ STATS_MAXSIZE, "max cache size ", display_size, FLAG_NOZERO },
{ STATS_OBSOLETE_MAXFILES, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
{ STATS_OBSOLETE_MAXSIZE, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
{ STATS_NONE, NULL, NULL, 0 }
};
@ -151,13 +146,6 @@ end:
free(tmp_file);
}
/* fill in some default stats values */
static void
stats_default(struct counters *counters)
{
counters->data[STATS_MAXSIZE] += DEFAULT_MAXSIZE / 16;
}
static void
init_counter_updates(void)
{
@ -188,8 +176,6 @@ stats_read(const char *sfile, struct counters *counters)
char *data = read_text_file(sfile, 1024);
if (data) {
parse_stats(counters, data);
} else {
stats_default(counters);
}
free(data);
}
@ -228,7 +214,6 @@ stats_flush(void)
* A NULL stats_file means that we didn't get past calculate_object_hash(),
* so we just choose one of stats files in the 16 subdirectories.
*/
assert(conf);
stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16);
stats_file = format("%s/stats", stats_dir);
free(stats_dir);
@ -254,20 +239,18 @@ stats_flush(void)
}
}
if (counters->data[STATS_MAXFILES] != 0 &&
counters->data[STATS_NUMFILES] > counters->data[STATS_MAXFILES]) {
if (conf->max_files != 0
&& counters->data[STATS_NUMFILES] > conf->max_files / 16) {
need_cleanup = true;
}
if (counters->data[STATS_MAXSIZE] != 0 &&
counters->data[STATS_TOTALSIZE] > counters->data[STATS_MAXSIZE]) {
if (conf->max_size != 0
&& counters->data[STATS_TOTALSIZE] > conf->max_size / 16) {
need_cleanup = true;
}
if (need_cleanup) {
char *p = dirname(stats_file);
cleanup_dir(p,
counters->data[STATS_MAXFILES],
counters->data[STATS_MAXSIZE]);
cleanup_dir(conf, p);
free(p);
}
}
@ -289,7 +272,7 @@ stats_get_pending(enum stats stat)
/* sum and display the total stats for all cache dirs */
void
stats_summary(void)
stats_summary(struct conf *conf)
{
int dir, i;
struct counters *counters = counters_init(STATS_END);
@ -308,11 +291,6 @@ stats_summary(void)
stats_read(fname, counters);
free(fname);
/* oh what a nasty hack ... */
if (dir == -1) {
counters->data[STATS_MAXSIZE] = 0;
}
}
printf("cache directory %s\n", conf->cache_dir);
@ -321,6 +299,9 @@ stats_summary(void)
for (i = 0; stats_info[i].message; i++) {
enum stats stat = stats_info[i].stat;
if (stats_info[i].flags & FLAG_NEVER) {
continue;
}
if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
continue;
}
@ -334,6 +315,15 @@ stats_summary(void)
}
}
if (conf->max_files != 0) {
printf("max files %8u\n", conf->max_files);
}
if (conf->max_size != 0) {
printf("max cache size ");
display_size(conf->max_size);
printf("\n");
}
counters_free(counters);
}
@ -371,59 +361,17 @@ stats_zero(void)
/* Get the per directory limits */
void
stats_get_limits(const char *dir, unsigned *maxfiles, unsigned *maxsize)
stats_get_obsolete_limits(const char *dir, unsigned *maxfiles, unsigned *maxsize)
{
struct counters *counters = counters_init(STATS_END);
char *sname = format("%s/stats", dir);
stats_read(sname, counters);
*maxfiles = counters->data[STATS_MAXFILES];
*maxsize = counters->data[STATS_MAXSIZE];
*maxfiles = counters->data[STATS_OBSOLETE_MAXFILES];
*maxsize = counters->data[STATS_OBSOLETE_MAXSIZE];
free(sname);
counters_free(counters);
}
/* set the per directory limits */
int
stats_set_limits(long maxfiles, long maxsize)
{
int dir;
assert(conf);
if (maxfiles != -1) {
maxfiles /= 16;
}
if (maxsize != -1) {
maxsize /= 16;
}
/* set the limits in each directory */
for (dir = 0; dir <= 0xF; dir++) {
char *fname, *cdir;
cdir = format("%s/%1x", conf->cache_dir, dir);
fname = format("%s/stats", cdir);
free(cdir);
if (lockfile_acquire(fname, lock_staleness_limit)) {
struct counters *counters = counters_init(STATS_END);
stats_read(fname, counters);
if (maxfiles != -1) {
counters->data[STATS_MAXFILES] = maxfiles;
}
if (maxsize != -1) {
counters->data[STATS_MAXSIZE] = maxsize;
}
stats_write(fname, counters);
lockfile_release(fname);
counters_free(counters);
}
free(fname);
}
return 0;
}
/* set the per directory sizes */
void
stats_set_sizes(const char *dir, size_t num_files, size_t total_size)

17
test.sh
View File

@ -67,7 +67,7 @@ randcode() {
getstat() {
stat="$1"
value=`$CCACHE -s | grep "$stat" | cut -c34-40`
value=`$CCACHE -s | grep "$stat" | cut -c34-`
echo $value
}
@ -1596,7 +1596,7 @@ cleanup_suite() {
$CCACHE -C >/dev/null
prepare_cleanup_test $CCACHE_DIR/a
touch $CCACHE_DIR/a/abcd.unknown
$CCACHE -c >/dev/null # update counters
$CCACHE -F 0 -M 0 -c >/dev/null # update counters
checkstat 'files in cache' 31
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
@ -1789,6 +1789,15 @@ EOF
checkstat 'cache miss' 2
}
upgrade_suite() {
testname="keep maxfiles and maxsize settings"
rm -rf $CCACHE_DIR $CCACHE_CONFIG_PATH
mkdir -p $CCACHE_DIR/0
echo "0 0 0 0 0 0 0 0 0 0 0 0 0 2000 131072" >$CCACHE_DIR/0/stats
checkstat 'max files' 32000
checkstat 'max cache size' '2.0 Gbytes'
}
######################################################################
# main program
@ -1821,8 +1830,9 @@ CCACHE_DIR=`pwd`/.ccache
export CCACHE_DIR
CCACHE_LOGFILE=`pwd`/ccache.log
export CCACHE_LOGFILE
CCACHE_CONFIG_PATH=/dev/null
CCACHE_CONFIG_PATH=`pwd`/ccache.conf
export CCACHE_CONFIG_PATH
touch $CCACHE_CONFIG_PATH
# ---------------------------------------
@ -1840,6 +1850,7 @@ readonly
extrafiles
cleanup
pch
upgrade
"
host_os="`uname -s`"

1
util.c
View File

@ -18,7 +18,6 @@
*/
#include "ccache.h"
#include "conf.h"
#include <zlib.h>