This is primaily done to avoid overflowing timestamp values in 2038.
bool keep_comments_cpp() const;
double limit_multiple() const;
const std::string& log_file() const;
- uint32_t max_files() const;
+ uint64_t max_files() const;
uint64_t max_size() const;
const std::string& path() const;
bool pch_external_checksum() const;
void set_ignore_options(const std::string& value);
void set_inode_cache(bool value);
void set_limit_multiple(double value);
- void set_max_files(uint32_t value);
+ void set_max_files(uint64_t value);
void set_max_size(uint64_t value);
void set_run_second_cpp(bool value);
bool m_keep_comments_cpp = false;
double m_limit_multiple = 0.8;
std::string m_log_file = "";
- uint32_t m_max_files = 0;
+ uint64_t m_max_files = 0;
uint64_t m_max_size = 5ULL * 1000 * 1000 * 1000;
std::string m_path = "";
bool m_pch_external_checksum = false;
return m_log_file;
}
-inline uint32_t
+inline uint64_t
Config::max_files() const
{
return m_max_files;
}
inline void
-Config::set_max_files(uint32_t value)
+Config::set_max_files(uint64_t value)
{
m_max_files = value;
}
}
// clang-format off
-unsigned&
+uint64_t&
Counters::operator[](Statistic index)
// clang-format on
{
}
// clang-format off
-unsigned
+uint64_t
Counters::operator[](Statistic index) const
// clang-format on
{
-// Copyright (C) 2010-2019 Joel Rosdahl and other contributors
+// Copyright (C) 2010-2020 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
enum class Statistic;
-// A simple wrapper around a vector of integers
-// used for the statistics counters.
+// A simple wrapper around a vector of integers used for the statistics
+// counters.
class Counters
{
public:
Counters();
- unsigned& operator[](Statistic index);
- unsigned operator[](Statistic index) const;
+ uint64_t& operator[](Statistic index);
+ uint64_t operator[](Statistic index) const;
size_t size() const;
bool all_zero() const;
private:
- std::vector<unsigned> m_counters;
+ std::vector<uint64_t> m_counters;
};
#endif
}
-uint32_t
+uint64_t
parse_duration(const std::string& duration)
{
unsigned factor = 0;
// On Windows: Backslashes are replaced with forward slashes.
std::string normalize_absolute_path(nonstd::string_view path);
-// Parse `duration`, an unsigned 32-bit integer with d (days) or s (seconds)
-// suffix, into seconds. Throws `Error` on error.
-uint32_t parse_duration(const std::string& duration);
+// Parse `duration`, an unsigned integer with d (days) or s (seconds) suffix,
+// into seconds. Throws `Error` on error.
+uint64_t parse_duration(const std::string& duration);
// Parse a string into a signed integer.
//
return;
}
- unsigned max_files;
+ uint64_t max_files;
uint64_t max_size;
std::string stats_dir = fmt::format("{}/0", config.cache_dir());
if (Stat::stat(stats_dir)) {
delete_file(const std::string& path,
uint64_t size,
uint64_t* cache_size,
- uint32_t* files_in_cache)
+ uint64_t* files_in_cache)
{
bool deleted = Util::unlink_safe(path, Util::UnlinkLog::ignore_failure);
if (!deleted && errno != ENOENT && errno != ESTALE) {
void
clean_old(const Context& ctx,
const Util::ProgressReceiver& progress_receiver,
- time_t max_age)
+ uint64_t max_age)
{
Util::for_each_level_1_subdir(
ctx.config.cache_dir(),
void
clean_up_dir(const std::string& subdir,
uint64_t max_size,
- uint32_t max_files,
- time_t max_age,
+ uint64_t max_files,
+ uint64_t max_age,
const Util::ProgressReceiver& progress_receiver)
{
log("Cleaning up cache directory {}", subdir);
subdir, [&](double progress) { progress_receiver(progress / 3); }, files);
uint64_t cache_size = 0;
- uint32_t files_in_cache = 0;
+ uint64_t files_in_cache = 0;
time_t current_time = time(nullptr);
for (size_t i = 0; i < files.size();
if ((max_size == 0 || cache_size <= max_size)
&& (max_files == 0 || files_in_cache <= max_files)
- && (max_age == 0 || file->lstat().mtime() > (current_time - max_age))) {
+ && (max_age == 0
+ || file->lstat().mtime()
+ > (current_time - static_cast<int64_t>(max_age)))) {
break;
}
void clean_old(const Context& ctx,
const Util::ProgressReceiver& progress_receiver,
- time_t max_age);
+ uint64_t max_age);
void clean_up_dir(const std::string& subdir,
uint64_t max_size,
- uint32_t max_files,
- time_t max_age,
+ uint64_t max_files,
+ uint64_t max_age,
const Util::ProgressReceiver& progress_receiver);
void clean_up_all(const Config& config,
const char* p = buf.c_str();
while (true) {
char* p2;
- long val = strtol(p, &p2, 10);
+ unsigned long long val = std::strtoull(p, &p2, 10);
if (p2 == p) {
break;
}
static double
stats_hit_rate(const Counters& counters)
{
- unsigned direct = counters[Statistic::direct_cache_hit];
- unsigned preprocessed = counters[Statistic::preprocessed_cache_hit];
- unsigned hit = direct + preprocessed;
- unsigned miss = counters[Statistic::cache_miss];
- unsigned total = hit + miss;
+ uint64_t direct = counters[Statistic::direct_cache_hit];
+ uint64_t preprocessed = counters[Statistic::preprocessed_cache_hit];
+ uint64_t hit = direct + preprocessed;
+ uint64_t miss = counters[Statistic::cache_miss];
+ uint64_t total = hit + miss;
return total > 0 ? (100.0 * hit) / total : 0.0;
}
static void
stats_collect(const Config& config, Counters& counters, time_t* last_updated)
{
- unsigned zero_timestamp = 0;
+ uint64_t zero_timestamp = 0;
*last_updated = 0;
double factor = config.limit_multiple() / 16;
uint64_t max_size = round(config.max_size() * factor);
uint32_t max_files = round(config.max_files() * factor);
- uint32_t max_age = 0;
+ time_t max_age = 0;
clean_up_dir(
subdir, max_size, max_files, max_age, [](double /*progress*/) {});
}
// Get the per-directory limits.
void
stats_get_obsolete_limits(const std::string& dir,
- unsigned* maxfiles,
+ uint64_t* maxfiles,
uint64_t* maxsize)
{
assert(maxfiles);
std::string sname = dir + "/stats";
stats_read(sname, counters);
*maxfiles = counters[Statistic::obsolete_max_files];
- *maxsize =
- static_cast<uint64_t>(counters[Statistic::obsolete_max_size]) * 1024;
+ *maxsize = counters[Statistic::obsolete_max_size] * 1024;
}
// Set the per-directory sizes.
void
-stats_set_sizes(const std::string& dir, unsigned num_files, uint64_t total_size)
+stats_set_sizes(const std::string& dir, uint64_t num_files, uint64_t total_size)
{
Counters counters;
std::string statsfile = dir + "/stats";
// Count directory cleanup run.
void
-stats_add_cleanup(const std::string& dir, unsigned count)
+stats_add_cleanup(const std::string& dir, uint64_t count)
{
Counters counters;
std::string statsfile = dir + "/stats";
void stats_update_size(Counters& counters, int64_t size, int files);
void stats_get_obsolete_limits(const std::string& dir,
- unsigned* maxfiles,
+ uint64_t* maxfiles,
uint64_t* maxsize);
void stats_set_sizes(const std::string& dir,
- unsigned num_files,
+ uint64_t num_files,
uint64_t total_size);
-void stats_add_cleanup(const std::string& dir, unsigned count);
+void stats_add_cleanup(const std::string& dir, uint64_t count);
void stats_read(const std::string& path, Counters& counters);
void stats_write(const std::string& path, const Counters& counters);
expect_stat() {
local stat="$1"
local expected_value="$2"
- local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c34-))"
+ local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c33-))"
if [ "$expected_value" != "$value" ]; then
test_failed "Expected \"$stat\" to be $expected_value, actual $value"
expect_contains "$stats_file" 101
expect_newer_than "$stats_file" "$CCACHE_DIR/timestamp_reference"
+ # -------------------------------------------------------------------------
+ TEST "stats file with large counter values"
+
+ mkdir -p "$CCACHE_DIR/4/"
+ stats_file="$CCACHE_DIR/4/stats"
+
+ echo "0 0 0 0 1234567890123456789" >"$stats_file"
+
+ expect_stat 'cache miss' 1234567890123456789
+ $CCACHE_COMPILE -c test1.c
+ expect_stat 'cache miss' 1234567890123456790
+
# -------------------------------------------------------------------------
TEST "CCACHE_RECACHE"