Teach cleanup code to calculate actual cache size and number of files again

This commit is contained in:
Joel Rosdahl 2010-06-09 20:03:20 +02:00
parent 9c0d14557d
commit 407db453ba
2 changed files with 72 additions and 76 deletions

View File

@ -38,38 +38,13 @@ static struct files {
time_t mtime;
size_t size; /* In KiB. */
} **files;
static unsigned allocated;
static unsigned num_files;
static size_t total_object_size;
static size_t total_object_files;
static size_t object_size_threshold;
static size_t object_files_threshold;
static unsigned allocated; /* Size of the files array. */
static unsigned num_files; /* Number of used entries in the files array. */
static int is_object_file(const char *fname)
{
int i;
int len;
len = strlen(fname);
if (len < 2) {
return 0;
}
/* ccache 3.0 and later: */
if (len >= 2 && fname[len - 2] == '.' && fname[len - 1] == 'o') {
return 1;
}
/* ccache 2.4 and earlier: */
for (i = len - 1; i >= 0; i--) {
if (fname[i] == '.') {
return 0;
} else if (fname[i] == '-') {
return 1;
}
}
return 1;
}
static size_t cache_size; /* In KiB. */
static size_t files_in_cache;
static size_t cache_size_threshold;
static size_t files_in_cache_threshold;
/* File comparison function that orders files in mtime order, oldest first. */
static int files_compare(struct files **f1, struct files **f2)
@ -117,20 +92,16 @@ static void traverse_fn(const char *fname, struct stat *st)
files[num_files]->fname = x_strdup(fname);
files[num_files]->mtime = st->st_mtime;
files[num_files]->size = file_size(st) / 1024;
if (is_object_file(fname)) {
total_object_files += 1;
total_object_size += files[num_files]->size;
}
cache_size += files[num_files]->size;
files_in_cache++;
num_files++;
}
static void delete_file(const char *path, size_t size)
{
if (unlink(path) == 0) {
if (is_object_file(path)) {
total_object_files -= 1;
total_object_size -= size;
}
cache_size -= size;
files_in_cache--;
} else if (errno != ENOENT) {
cc_log("Failed to unlink %s (%s)", path, strerror(errno));
}
@ -166,10 +137,10 @@ static void sort_and_clean(void)
/* delete enough files to bring us below the threshold */
for (i = 0; i < num_files; i++) {
if ((object_size_threshold == 0
|| total_object_size <= object_size_threshold)
&& (object_files_threshold == 0
|| total_object_files <= object_files_threshold)) {
if ((cache_size_threshold == 0
|| cache_size <= cache_size_threshold)
&& (files_in_cache_threshold == 0
|| files_in_cache <= files_in_cache_threshold)) {
break;
}
@ -209,12 +180,12 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
cc_log("Cleaning up cache directory %s", dir);
object_size_threshold = maxsize * LIMIT_MULTIPLE;
object_files_threshold = maxfiles * LIMIT_MULTIPLE;
cache_size_threshold = maxsize * LIMIT_MULTIPLE;
files_in_cache_threshold = maxfiles * LIMIT_MULTIPLE;
num_files = 0;
total_object_files = 0;
total_object_size = 0;
cache_size = 0;
files_in_cache = 0;
/* build a list of files */
traverse(dir, traverse_fn);
@ -222,7 +193,7 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
/* clean the cache */
sort_and_clean();
stats_set_sizes(dir, total_object_files, total_object_size);
stats_set_sizes(dir, files_in_cache, cache_size);
/* free it up */
for (i = 0; i < num_files; i++) {
@ -237,8 +208,8 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
files = NULL;
num_files = 0;
total_object_files = 0;
total_object_size = 0;
cache_size = 0;
files_in_cache = 0;
}
/* cleanup in all cache subdirs */

77
test.sh
View File

@ -1330,19 +1330,20 @@ EOF
prepare_cleanup_test() {
dir=$1
rm -rf $dir
mkdir -p $dir
i=0
while [ $i -lt 10 ]; do
dd if=/dev/zero of=$dir/result$i-4096.o count=1 bs=4096 2>/dev/null
touch $dir/result$i-4096.stderr
touch $dir/result$i-4096.d
dd if=/dev/zero of=$dir/result$i-4017.o count=1 bs=4017 2>/dev/null
touch $dir/result$i-4017.stderr
touch $dir/result$i-4017.d
if [ $i -gt 5 ]; then
backdate $dir/result$i-4096.o
backdate $dir/result$i-4017.stderr
fi
i=`expr $i + 1`
done
# NUMFILES: 10, TOTALSIZE: 10 KiB, MAXFILES: 0, MAXSIZE: 0
echo "0 0 0 0 0 0 0 0 0 0 0 10 40 0 0" >$dir/stats
# NUMFILES: 30, TOTALSIZE: 40 KiB, MAXFILES: 0, MAXSIZE: 0
echo "0 0 0 0 0 0 0 0 0 0 0 30 40 0 0" >$dir/stats
}
cleanup_suite() {
@ -1352,6 +1353,7 @@ cleanup_suite() {
checkfilecount 0 '*.o' $CCACHE_DIR
checkfilecount 0 '*.d' $CCACHE_DIR
checkfilecount 0 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 0
testname="forced cleanup, no limits"
$CCACHE -C >/dev/null
@ -1361,25 +1363,27 @@ cleanup_suite() {
checkfilecount 10 '*.o' $CCACHE_DIR
checkfilecount 10 '*.d' $CCACHE_DIR
checkfilecount 10 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 30
testname="forced cleanup, file limit"
$CCACHE -C >/dev/null
prepare_cleanup_test $CCACHE_DIR/a
# (9/10) * 10 * 16 = 144
$CCACHE -F 144 -M 0 >/dev/null
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
$CCACHE -c >/dev/null
# floor(0.8 * 9) = 7
checkfilecount 7 '*.o' $CCACHE_DIR
checkfilecount 7 '*.d' $CCACHE_DIR
checkfilecount 7 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 21
for i in 0 1 2 3 4 5 9; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ ! -f $file ]; then
test_failed "File $file removed when it shouldn't"
fi
done
for i in 6 7 8; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ -f $file ]; then
test_failed "File $file not removed when it should"
fi
@ -1395,14 +1399,15 @@ cleanup_suite() {
checkfilecount 3 '*.o' $CCACHE_DIR
checkfilecount 3 '*.d' $CCACHE_DIR
checkfilecount 3 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 9
for i in 3 4 5; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ ! -f $file ]; then
test_failed "File $file removed when it shouldn't"
fi
done
for i in 0 1 2 6 7 8 9; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ -f $file ]; then
test_failed "File $file not removed when it should"
fi
@ -1413,35 +1418,40 @@ cleanup_suite() {
for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
prepare_cleanup_test $CCACHE_DIR/$x
done
# (9/10) * 10 * 16 = 144
$CCACHE -F 144 -M 0 >/dev/null
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
touch empty.c
checkfilecount 160 '*.o' $CCACHE_DIR
checkstat 'files in cache' 160
checkfilecount 160 '*.d' $CCACHE_DIR
checkfilecount 160 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 480
$CCACHE $COMPILER -c empty.c -o empty.o
# floor(0.8 * 10) = 7
# floor(0.8 * 9) = 7
checkfilecount 157 '*.o' $CCACHE_DIR
checkstat 'files in cache' 157
checkfilecount 156 '*.d' $CCACHE_DIR
checkfilecount 156 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 469
testname="sibling cleanup"
$CCACHE -C >/dev/null
prepare_cleanup_test $CCACHE_DIR/a
# (9/10) * 10 * 16 = 144
$CCACHE -F 144 -M 0 >/dev/null
backdate $CCACHE_DIR/a/result2-4096.stderr
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
backdate $CCACHE_DIR/a/result2-4017.stderr
$CCACHE -c >/dev/null
# floor(0.8 * 9) = 7
checkfilecount 7 '*.o' $CCACHE_DIR
checkfilecount 7 '*.d' $CCACHE_DIR
checkfilecount 7 '*.stderr' $CCACHE_DIR
checkstat 'files in cache' 21
for i in 0 1 3 4 5 8 9; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ ! -f $file ]; then
test_failed "File $file removed when it shouldn't"
fi
done
for i in 2 6 7; do
file=$CCACHE_DIR/a/result$i-4096.o
file=$CCACHE_DIR/a/result$i-4017.o
if [ -f $file ]; then
test_failed "File $file not removed when it should"
fi
@ -1450,25 +1460,40 @@ cleanup_suite() {
testname="new unknown file"
$CCACHE -C >/dev/null
prepare_cleanup_test $CCACHE_DIR/a
# (9/10) * 10 * 16 = 144
$CCACHE -F 144 -M 0 >/dev/null
touch $CCACHE_DIR/a/abcd.unknown
$CCACHE -c >/dev/null # update counters
checkstat 'files in cache' 31
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
$CCACHE -c >/dev/null
if [ ! -f $CCACHE_DIR/a/abcd.unknown ]; then
test_failed "$CCACHE_DIR/a/abcd.unknown removed"
fi
checkstat 'files in cache' 19
testname="old unknown file"
$CCACHE -C >/dev/null
prepare_cleanup_test $CCACHE_DIR/a
# (9/10) * 10 * 16 = 144
$CCACHE -F 144 -M 0 >/dev/null
# (9/10) * 30 * 16 = 432
$CCACHE -F 432 -M 0 >/dev/null
touch $CCACHE_DIR/a/abcd.unknown
backdate $CCACHE_DIR/a/abcd.unknown
$CCACHE -c >/dev/null
if [ -f $CCACHE_DIR/a/abcd.unknown ]; then
test_failed "$CCACHE_DIR/a/abcd.unknown not removed"
fi
testname="cleanup of tmp files"
$CCACHE -C >/dev/null
touch $CCACHE_DIR/a/abcd.tmp.efgh
$CCACHE -c >/dev/null # update counters
checkstat 'files in cache' 1
backdate $CCACHE_DIR/a/abcd.tmp.efgh
$CCACHE -c >/dev/null
if [ -f $CCACHE_DIR/a/abcd.tmp.efgh ]; then
test_failed "$CCACHE_DIR/a/abcd.tmp.unknown not removed"
fi
checkstat 'files in cache' 0
}
######################################################################