// Use stats file in the level one subdirectory for cache bookkeeping counters
// since cleanup is performed on level one. Use stats file in the level two
// subdirectory for other counters to reduce lock contention.
- const bool updated_file_size_or_count =
+ const bool use_stats_on_level_1 =
counter_updates.get(Statistic::cache_size_kibibyte) != 0
|| counter_updates.get(Statistic::files_in_cache) != 0;
std::string level_string = fmt::format("{:x}", name.bytes()[0] >> 4);
- if (!updated_file_size_or_count) {
+ if (!use_stats_on_level_1) {
level_string += fmt::format("/{:x}", name.bytes()[0] & 0xF);
}
const auto stats_file =
return nullopt;
}
- const auto wanted_level =
- calculate_wanted_cache_level(counters->get(Statistic::files_in_cache));
- const auto wanted_path = Util::get_path_in_cache(
- ctx.config.cache_dir(), wanted_level, name.to_string() + file_suffix);
- if (current_path != wanted_path) {
- Util::ensure_dir_exists(Util::dir_name(wanted_path));
- log("Moving {} to {}", current_path, wanted_path);
- try {
- Util::rename(current_path, wanted_path);
- } catch (const Error&) {
- // Two ccache processes may move the file at the same time, so failure to
- // rename is OK.
+ if (use_stats_on_level_1) {
+ // Only consider moving the cache file to another level when we have read
+ // the level 1 stats file since it's only then we know the proper
+ // files_in_cache value.
+ const auto wanted_level =
+ calculate_wanted_cache_level(counters->get(Statistic::files_in_cache));
+ const auto wanted_path = Util::get_path_in_cache(
+ ctx.config.cache_dir(), wanted_level, name.to_string() + file_suffix);
+ if (current_path != wanted_path) {
+ Util::ensure_dir_exists(Util::dir_name(wanted_path));
+ log("Moving {} to {}", current_path, wanted_path);
+ try {
+ Util::rename(current_path, wanted_path);
+ } catch (const Error&) {
+ // Two ccache processes may move the file at the same time, so failure
+ // to rename is OK.
+ }
}
}
return counters;
expect_on_level R 2
expect_on_level M 2
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' $((files + 2))
+ expect_on_level R 2
+ expect_on_level M 2
+
# -------------------------------------------------------------------------
TEST "Level 3"
expect_on_level R 3
expect_on_level M 3
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' $((files + 2))
+ expect_on_level R 3
+ expect_on_level M 3
+
# -------------------------------------------------------------------------
TEST "Level 4"
expect_on_level R 4
expect_on_level M 4
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' $((files + 2))
+ expect_on_level R 4
+ expect_on_level M 4
+
# -------------------------------------------------------------------------
TEST "No deeper than 4 levels"
expect_stat 'files in cache' $((files + 2))
expect_on_level R 4
expect_on_level M 4
+
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' $((files + 2))
+ expect_on_level R 4
+ expect_on_level M 4
}