"\n"
"See also <http://ccache.samba.org>.\n";
-#ifndef DEFAULT_MAXSIZE
-#define DEFAULT_MAXSIZE (1024*1024)
-#endif
-
/* Global configuration data. */
struct conf *conf = NULL;
failed();
}
- stats_update_size(STATS_TOCACHE, added_bytes / 1024, added_files);
+ stats_update_size(STATS_TOCACHE, added_bytes, added_files);
/* Make sure we have a CACHEDIR.TAG
* This can be almost anywhere, but might as well do it near the end
} else {
cc_log("Stored in cache: %s", cached_dep);
stat(cached_dep, &st);
- stats_update_size(STATS_NONE, file_size(&st) / 1024, 1);
+ stats_update_size(STATS_NONE, file_size(&st), 1);
}
}
update_mtime(manifest_path);
stat(manifest_path, &st);
stats_update_size(STATS_NONE,
- (file_size(&st) - old_size) / 1024,
+ (file_size(&st) - old_size),
old_size == 0 ? 1 : 0);
} else {
cc_log("Failed to add object file hash to %s", manifest_path);
static void
create_initial_config_file(struct conf *conf, const char *path)
{
- unsigned max_files, max_size;
+ unsigned max_files;
+ uint64_t max_size;
char *stats_dir;
FILE *f;
struct stat st;
max_size *= 16;
} else {
max_files = 0;
- max_size = DEFAULT_MAXSIZE;
+ max_size = conf->max_size;
}
free(stats_dir);
ccache_main_options(int argc, char *argv[])
{
int c;
- size_t v;
char *errmsg;
enum longopts {
exit(0);
case 'F': /* --max-files */
- initialize();
- v = atoi(optarg);
- if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
- &errmsg)) {
- if (v == 0) {
- printf("Unset cache file limit\n");
+ {
+ unsigned files;
+ initialize();
+ files = atoi(optarg);
+ if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
+ &errmsg)) {
+ if (files == 0) {
+ printf("Unset cache file limit\n");
+ } else {
+ printf("Set cache file limit to %u\n", files);
+ }
} else {
- printf("Set cache file limit to %u\n", (unsigned)v);
+ fatal("could not set cache file limit: %s", errmsg);
}
- } else {
- fatal("could not set cache file limit: %s", errmsg);
}
break;
case 'M': /* --max-size */
- initialize();
- parse_size_with_suffix(optarg, &v);
- if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
- &errmsg)) {
- if (v == 0) {
- printf("Unset cache size limit\n");
+ {
+ uint64_t size;
+ initialize();
+ if (!parse_size_with_suffix(optarg, &size)) {
+ fatal("invalid size: %s", optarg);
+ }
+ if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
+ &errmsg)) {
+ if (size == 0) {
+ printf("Unset cache size limit\n");
+ } else {
+ char *s = format_human_readable_size(size);
+ printf("Set cache size limit to %s\n", s);
+ free(s);
+ }
} else {
- char *s = format_human_readable_size(v);
- printf("Set cache size limit to %s\n", s);
- free(s);
+ fatal("could not set cache size limit: %s", errmsg);
}
- } else {
- fatal("could not set cache size limit: %s", errmsg);
}
break;
char *remove_extension(const char *path);
size_t file_size(struct stat *st);
int safe_create_wronly(const char *fname);
-char *format_human_readable_size(size_t size);
-char *format_parsable_size_with_suffix(size_t size);
-bool parse_size_with_suffix(const char *str, size_t *size);
+char *format_human_readable_size(uint64_t size);
+char *format_parsable_size_with_suffix(uint64_t size);
+bool parse_size_with_suffix(const char *str, uint64_t *size);
char *x_realpath(const char *path);
char *gnu_getcwd(void);
#ifndef HAVE_STRTOK_R
unsigned stats_get_pending(enum stats stat);
void stats_zero(void);
void stats_summary(struct conf *conf);
-void stats_update_size(enum stats stat, size_t size, unsigned files);
+void stats_update_size(enum stats stat, uint64_t size, unsigned files);
void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
- unsigned *maxsize);
+ uint64_t *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);
static struct files {
char *fname;
time_t mtime;
- size_t size; /* In KiB. */
+ uint64_t size;
} **files;
static unsigned allocated; /* Size of the files array. */
static unsigned num_files; /* Number of used entries in the files array. */
-static size_t cache_size; /* In KiB. */
+static uint64_t cache_size;
static size_t files_in_cache;
-static size_t cache_size_threshold;
+static uint64_t cache_size_threshold;
static size_t files_in_cache_threshold;
/* File comparison function that orders files in mtime order, oldest first. */
files[num_files] = (struct files *)x_malloc(sizeof(struct files));
files[num_files]->fname = x_strdup(fname);
files[num_files]->mtime = st->st_mtime;
- files[num_files]->size = file_size(st) / 1024;
+ files[num_files]->size = file_size(st);
cache_size += files[num_files]->size;
files_in_cache++;
num_files++;
path = format("%s%s", base, extension);
if (lstat(path, &st) == 0) {
- delete_file(path, file_size(&st) / 1024);
+ delete_file(path, file_size(&st));
} else if (errno != ENOENT) {
cc_log("Failed to stat %s (%s)", path, strerror(errno));
}
static bool
parse_size(const char *str, void *result, char **errmsg)
{
- unsigned *value = (unsigned *)result;
- size_t size;
+ uint64_t *value = (uint64_t *)result;
+ uint64_t size;
*errmsg = NULL;
if (parse_size_with_suffix(str, &size)) {
*value = size;
conf->hash_dir = false;
conf->log_file = x_strdup("");
conf->max_files = 0;
- conf->max_size = 1024 * 1024; /* kilobyte */
+ conf->max_size = 1024 * 1024 * 1024;
conf->path = x_strdup("");
conf->prefix_command = x_strdup("");
conf->read_only = false;
bool hash_dir;
char *log_file;
unsigned max_files;
- unsigned max_size;
+ uint64_t max_size;
char *path;
char *prefix_command;
bool read_only;
#define FLAG_ALWAYS 2 /* always show, even if zero */
#define FLAG_NEVER 4 /* never show */
-static void display_size(size_t v);
+static void display_size_times_1024(uint64_t size);
/* statistics fields in display order */
static struct {
{ STATS_NOINPUT, "no input file ", NULL, 0 },
{ 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_TOTALSIZE, "cache size ", display_size_times_1024 , FLAG_NOZERO|FLAG_ALWAYS },
{ STATS_OBSOLETE_MAXFILES, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
{ STATS_OBSOLETE_MAXSIZE, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
{ STATS_NONE, NULL, NULL, 0 }
};
static void
-display_size(size_t v)
+display_size(uint64_t size)
{
- char *s = format_human_readable_size(v);
+ char *s = format_human_readable_size(size);
printf("%15s", s);
free(s);
}
+static void
+display_size_times_1024(uint64_t size)
+{
+ display_size(size * 1024);
+}
+
/* parse a stats file from a buffer - adding to the counters */
static void
parse_stats(struct counters *counters, const char *buf)
* 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)
+stats_update_size(enum stats stat, uint64_t size, unsigned files)
{
init_counter_updates();
if (stat != STATS_NONE) {
counter_updates->data[stat]++;
}
counter_updates->data[STATS_NUMFILES] += files;
- counter_updates->data[STATS_TOTALSIZE] += size;
+ counter_updates->data[STATS_TOTALSIZE] += size / 1024;
}
/* Read in the stats from one directory and add to the counters. */
need_cleanup = true;
}
if (conf->max_size != 0
- && counters->data[STATS_TOTALSIZE] > conf->max_size / 16) {
+ && counters->data[STATS_TOTALSIZE] * 1024 > conf->max_size / 16) {
need_cleanup = true;
}
/* Get the per directory limits */
void
-stats_get_obsolete_limits(const char *dir, unsigned *maxfiles, unsigned *maxsize)
+stats_get_obsolete_limits(const char *dir, unsigned *maxfiles, uint64_t *maxsize)
{
struct counters *counters = counters_init(STATS_END);
char *sname = format("%s/stats", dir);
stats_read(sname, counters);
*maxfiles = counters->data[STATS_OBSOLETE_MAXFILES];
- *maxsize = counters->data[STATS_OBSOLETE_MAXSIZE];
+ *maxsize = counters->data[STATS_OBSOLETE_MAXSIZE] * 1024;
free(sname);
counters_free(counters);
}
if (lockfile_acquire(statsfile, lock_staleness_limit)) {
stats_read(statsfile, counters);
counters->data[STATS_NUMFILES] = num_files;
- counters->data[STATS_TOTALSIZE] = total_size;
+ counters->data[STATS_TOTALSIZE] = total_size / 1024;
stats_write(statsfile, counters);
lockfile_release(statsfile);
}
CHECK(!conf->hash_dir);
CHECK_STR_EQ("", conf->log_file);
CHECK_INT_EQ(0, conf->max_files);
- CHECK_INT_EQ(1024*1024, conf->max_size);
+ CHECK_INT_EQ(1024 * 1024 * 1024, conf->max_size);
CHECK_STR_EQ("", conf->path);
CHECK_STR_EQ("", conf->prefix_command);
CHECK(!conf->read_only);
CHECK(conf->hash_dir);
CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
CHECK_INT_EQ(17, conf->max_files);
- CHECK_INT_EQ(123 * 1024, conf->max_size);
+ CHECK_INT_EQ(123 * 1024 * 1024, conf->max_size);
CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
CHECK(conf->read_only);
TEST(format_human_readable_size)
{
- CHECK_STR_EQ_FREE2("0 Kbytes", format_human_readable_size(0));
- CHECK_STR_EQ_FREE2("42 Kbytes", format_human_readable_size(42));
- CHECK_STR_EQ_FREE2("1.0 Mbytes", format_human_readable_size(1024));
- CHECK_STR_EQ_FREE2("1.2 Mbytes", format_human_readable_size(1234));
- CHECK_STR_EQ_FREE2("438.5 Mbytes", format_human_readable_size(438.5 * 1024));
- CHECK_STR_EQ_FREE2("1.0 Gbytes", format_human_readable_size(1024 * 1024));
+ CHECK_STR_EQ_FREE2("0 bytes", format_human_readable_size(0));
+ CHECK_STR_EQ_FREE2("42.0 Kbytes", format_human_readable_size(42 * 1024));
+ CHECK_STR_EQ_FREE2("1.0 Mbytes", format_human_readable_size(1024 * 1024));
+ CHECK_STR_EQ_FREE2("1.2 Mbytes", format_human_readable_size(1234 * 1024));
+ CHECK_STR_EQ_FREE2("438.5 Mbytes",
+ format_human_readable_size(438.5 * 1024 * 1024));
+ CHECK_STR_EQ_FREE2("1.0 Gbytes",
+ format_human_readable_size(1024 * 1024 * 1024));
CHECK_STR_EQ_FREE2("17.1 Gbytes",
- format_human_readable_size(17.11 * 1024 * 1024));
+ format_human_readable_size(17.11 * 1024 * 1024 * 1024));
}
TEST(format_parsable_size_with_suffix)
{
CHECK_STR_EQ_FREE2("0", format_parsable_size_with_suffix(0));
- CHECK_STR_EQ_FREE2("42K", format_parsable_size_with_suffix(42));
- CHECK_STR_EQ_FREE2("1.0M", format_parsable_size_with_suffix(1024));
- CHECK_STR_EQ_FREE2("1.2M", format_parsable_size_with_suffix(1234));
+ CHECK_STR_EQ_FREE2("42.0K", format_parsable_size_with_suffix(42 * 1024));
+ CHECK_STR_EQ_FREE2("1.0M", format_parsable_size_with_suffix(1024 * 1024));
+ CHECK_STR_EQ_FREE2("1.2M", format_parsable_size_with_suffix(1234 * 1024));
CHECK_STR_EQ_FREE2("438.5M",
- format_parsable_size_with_suffix(438.5 * 1024));
+ format_parsable_size_with_suffix(438.5 * 1024 * 1024));
CHECK_STR_EQ_FREE2("1.0G",
- format_parsable_size_with_suffix(1024 * 1024));
- CHECK_STR_EQ_FREE2("17.1G",
- format_parsable_size_with_suffix(17.11 * 1024 * 1024));
+ format_parsable_size_with_suffix(1024 * 1024 * 1024));
+ CHECK_STR_EQ_FREE2(
+ "17.1G",
+ format_parsable_size_with_suffix(17.11 * 1024 * 1024 * 1024));
}
TEST(parse_size_with_suffix)
{
- size_t size;
+ uint64_t size;
CHECK(parse_size_with_suffix("0", &size));
CHECK_INT_EQ(0, size);
CHECK(parse_size_with_suffix("42K", &size));
- CHECK_INT_EQ(42, size);
+ CHECK_INT_EQ(42 * 1024, size);
CHECK(parse_size_with_suffix("1.0M", &size));
- CHECK_INT_EQ(1024, size);
+ CHECK_INT_EQ(1024 * 1024, size);
CHECK(parse_size_with_suffix("1.1M", &size));
- CHECK_INT_EQ(1.1 * 1024, size);
+ CHECK_INT_EQ(1.1 * 1024 * 1024, size);
CHECK(parse_size_with_suffix("438.5M", &size));
- CHECK_INT_EQ(438.5 * 1024, size);
+ CHECK_INT_EQ(438.5 * 1024 * 1024, size);
CHECK(parse_size_with_suffix("1.0G", &size));
- CHECK_INT_EQ(1024 * 1024, size);
+ CHECK_INT_EQ(1024 * 1024 * 1024, size);
CHECK(parse_size_with_suffix("17.1G", &size));
- CHECK_INT_EQ(17.1 * 1024 * 1024, size);
+ CHECK_INT_EQ(17.1 * 1024 * 1024 * 1024, size);
}
TEST_SUITE_END
return fd;
}
-/* Format a size (in KiB) as a human-readable string. Caller frees. */
+/* Format a size as a human-readable string. Caller frees. */
char *
-format_human_readable_size(size_t v)
+format_human_readable_size(uint64_t v)
{
char *s;
- if (v >= 1024*1024) {
- s = format("%.1f Gbytes", v/((double)(1024*1024)));
+ if (v >= 1024*1024*1024) {
+ s = format("%.1f Gbytes", v/((double)(1024*1024*1024)));
+ } else if (v >= 1024*1024) {
+ s = format("%.1f Mbytes", v/((double)(1024*1024)));
} else if (v >= 1024) {
- s = format("%.1f Mbytes", v/((double)(1024)));
+ s = format("%.1f Kbytes", v/((double)(1024)));
} else {
- s = format("%.0f Kbytes", (double)v);
+ s = format("%u bytes", (unsigned)v);
}
return s;
}
/* Format a size (in KiB) as a human-readable string. Caller frees. */
char *
-format_parsable_size_with_suffix(size_t size)
+format_parsable_size_with_suffix(uint64_t size)
{
char *s;
- if (size >= 1024*1024) {
- s = format("%.1fG", size / ((double)(1024*1024)));
+ if (size >= 1024*1024*1024) {
+ s = format("%.1fG", size / ((double)(1024*1024*1024)));
+ } else if (size >= 1024*1024) {
+ s = format("%.1fM", size / ((double)(1024*1024)));
} else if (size >= 1024) {
- s = format("%.1fM", size / ((double)(1024)));
- } else if (size > 0) {
- s = format("%.0fK", (double)size);
+ s = format("%.1fK", size / ((double)(1024)));
} else {
- s = x_strdup("0");
+ s = format("%u", (unsigned)size);
}
return s;
}
/*
- * Parse a value in multiples of 1024 given a string that can end in K, M or G.
- * Default suffix: G.
+ * Parse a value given a string that can end in K, M or G. Default suffix: G.
*/
bool
-parse_size_with_suffix(const char *str, size_t *size)
+parse_size_with_suffix(const char *str, uint64_t *size)
{
char *endptr;
double x;
default:
return false;
}
- *size = x;
+ *size = x * 1024;
return true;
}