~~~~~~~~~~~~~
- The way the hashes are calculated has changed, so you won't get cache
- hits for compilation results stored by older ccache versions.
-
- - The statistics counters ``files in cache'' and ``cache size'' now only
- count object files. (Previously, files containing cached standard error
- output were counted as well.) The existing values of the two counters
- will be erroneous at first after the upgrade, but will correct themselves
- eventually when enough cleanups have been made, or when you run +ccache
- --cleanup+.
-
- - The ``max file'' and ``max cache size'' settings now specify thresholds
- for object files count and size.
-
- - Because of the changes mentioned above, you might as well clear the old
- cache directory with `ccache --cleanup` if you want, unless you plan to
- keep using an older ccache version.
+ hits for compilation results stored by older ccache versions. Because of
+ this, you might as well clear the old cache directory with `ccache
+ --cleanup` if you want, unless you plan to keep using an older ccache
+ version.
New features and improvements
char *tmp_stdout, *tmp_stderr, *tmp_obj;
struct stat st;
int status;
+ size_t added_bytes = 0;
+ unsigned added_files = 0;
x_asprintf(&tmp_stdout, "%s.tmp.stdout.%s", cached_obj, tmp_string());
x_asprintf(&tmp_stderr, "%s.tmp.stderr.%s", cached_obj, tmp_string());
failed();
}
cc_log("Stored in cache: %s", cached_stderr);
+ if (enable_compression) {
+ stat(cached_stderr, &st);
+ }
+ added_bytes += file_size(&st);
+ added_files += 1;
} else {
unlink(tmp_stderr);
}
failed();
} else {
cc_log("Stored in cache: %s", cached_obj);
+ stat(cached_obj, &st);
+ added_bytes += file_size(&st);
+ added_files += 1;
}
/*
failed();
}
- stats_tocache(file_size(&st));
+ stats_update_size(STATS_TOCACHE, added_bytes / 1024, added_files);
free(tmp_obj);
free(tmp_stderr);
/* Continue despite the error. */
} else {
cc_log("Stored in cache: %s", cached_dep);
+ stat(cached_dep, &st);
+ stats_update_size(STATS_NONE, file_size(&st) / 1024, 1);
}
}
&& put_object_in_manifest
&& included_files
&& !getenv("CCACHE_READONLY")) {
+ struct stat st;
+ size_t old_size = 0; /* in bytes */
+ if (stat(manifest_path, &st) == 0) {
+ old_size = file_size(&st);
+ }
if (manifest_put(manifest_path, cached_obj_hash, included_files)) {
- cc_log("Added object file hash to %s",
- manifest_path);
+ cc_log("Added object file hash to %s", manifest_path);
update_mtime(manifest_path);
+ stat(manifest_path, &st);
+ stats_update_size(
+ STATS_NONE,
+ (file_size(&st) - old_size) / 1024,
+ old_size == 0 ? 1 : 0);
} else {
- cc_log("Failed to add object file hash to %s",
- manifest_path);
+ cc_log("Failed to add object file hash to %s", manifest_path);
}
}
break;
case FROMCACHE_COMPILED_MODE:
+ // Stats already updated in to_cache().
break;
}
void stats_update(enum stats stat);
void stats_zero(void);
void stats_summary(void);
-void stats_tocache(size_t size);
+void stats_update_size(enum stats stat, size_t size, unsigned files);
void stats_read(const char *stats_file, unsigned counters[STATS_END]);
int stats_set_limits(long maxfiles, long maxsize);
size_t value_units(const char *s);
*-F, --max-files*='N'::
- Set the maximum number of object files allowed in the cache. The value is
- stored inside the cache directory and applies to all future compilations.
- Due to the way the value is stored the actual value used is always rounded
- down to the nearest multiple of 16.
+ Set the maximum number of files allowed in the cache. The value is stored
+ inside the cache directory and applies to all future compilations. Due to
+ the way the value is stored the actual value used is always rounded down to
+ the nearest multiple of 16.
*-h, --help*::
*-M, --max-size*='SIZE'::
- Set the maximum size of the object files stored in the cache. You can
- specify a value in gigabytes, megabytes or kilobytes by appending a G, M or
- K to the value. The default is gigabytes. The actual value stored is
- rounded down to the nearest multiple of 16 kilobytes.
+ Set the maximum size of the files stored in the cache. You can specify a
+ value in gigabytes, megabytes or kilobytes by appending a G, M or K to the
+ value. The default is gigabytes. The actual value stored is rounded down to
+ the nearest multiple of 16 kilobytes.
*-s, --show-stats*::
CACHE SIZE MANAGEMENT
---------------------
-By default ccache has a one gigabyte limit on the total size of object files in
-the cache and no maximum number of object files. You can set different limits
-using the *-M*/*--max-size* and *-F*/*--max-files* options. Use *ccache -s* to
-see the cache size and the currently configured limits (in addition to other
-various statistics).
+By default ccache has a one gigabyte limit on the total size of files in the
+cache and no maximum number of files. You can set different limits using the
+*-M*/*--max-size* and *-F*/*--max-files* options. Use *ccache -s* to see the
+cache size and the currently configured limits (in addition to other various
+statistics).
CACHE COMPRESSION
parse_stats(counters, buf);
}
-/* update the stats counter for this compile */
-static void stats_update_size(enum stats stat, size_t size)
+/*
+ * Update a statistics counter (unless it's STATS_NONE) and also record that a
+ * number of bytes and files have been added to the cache. Size is in KiB.
+ */
+void stats_update_size(enum stats stat, size_t size, unsigned files)
{
int fd;
unsigned counters[STATS_END];
x_asprintf(&stats_file, "%s/stats", cache_dir);
}
- /* open safely to try to prevent symlink races */
fd = safe_open(stats_file);
-
- /* still can't get it? don't bother ... */
if (fd == -1) return;
-
- memset(counters, 0, sizeof(counters));
-
if (write_lock_fd(fd) != 0) return;
- /* read in the old stats */
+ memset(counters, 0, sizeof(counters));
stats_read_fd(fd, counters);
- /* update them */
- counters[stat]++;
-
- /* on a cache miss we up the file count and size */
- if (stat == STATS_TOCACHE) {
- counters[STATS_NUMFILES] += 1;
- counters[STATS_TOTALSIZE] += size;
+ if (stat != STATS_NONE) {
+ counters[stat]++;
}
+ counters[STATS_NUMFILES] += files;
+ counters[STATS_TOTALSIZE] += size;
- /* and write them out */
write_stats(fd, counters);
close(fd);
- /* we might need to cleanup if the cache has now got too big */
if (counters[STATS_MAXFILES] != 0 &&
counters[STATS_NUMFILES] > counters[STATS_MAXFILES]) {
need_cleanup = 1;
}
}
-/* record a cache miss */
-void stats_tocache(size_t size)
-{
- /* convert size to kilobytes */
- size = size / 1024;
-
- stats_update_size(STATS_TOCACHE, size);
-}
-
/* update a normal stat */
void stats_update(enum stats stat)
{
- stats_update_size(stat, 0);
+ stats_update_size(stat, 0, 0);
}
/* read in the stats from one dir and add to the counters */
/* Trigger warning by having no return statement. */
}
EOF
+ checkstat 'files in cache' 3
$CCACHE_COMPILE -Wall -W -c stderr.c 2>/dev/null
num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
if [ $num -ne 1 ]; then
test_failed "$num stderr files found, expected 1"
fi
+ checkstat 'files in cache' 5
testname="zero-stats"
$CCACHE -z > /dev/null
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 0
+ checkstat 'files in cache' 5
testname="clear"
$CCACHE -C > /dev/null
##################################################################
# Check calculation of dependency file names.
- $CCACHE -z >/dev/null
+ $CCACHE -Cz >/dev/null
+ checkstat 'files in cache' 0
mkdir test.dir
- # Make sure the dependency file is in the cache:
- $CCACHE $COMPILER -MD -c test.c
for ext in .obj "" . .foo.bar; do
testname="dependency file calculation from object file 'test$ext'"
dep_file=test.dir/`echo test$ext | sed 's/\.[^.]*\$//'`.d
+ $CCACHE $COMPILER -MD -c test.c -o test.dir/test$ext
rm -f $dep_file
$CCACHE $COMPILER -MD -c test.c -o test.dir/test$ext
if [ ! -f $dep_file ]; then
fi
done
rm -rf test.dir
+ checkstat 'files in cache' 12
##################################################################
# Check that -Wp,-MD,file.d works.