]> git.ipfire.org Git - thirdparty/ccache.git/blame - src/InodeCache.hpp
chore: Use brace initialization for integer literals
[thirdparty/ccache.git] / src / InodeCache.hpp
CommitLineData
de637952 1// Copyright (C) 2020-2023 Joel Rosdahl and other contributors
213d9883
OL
2//
3// See doc/AUTHORS.adoc for a complete list of contributors.
4//
5// This program is free software; you can redistribute it and/or modify it
6// under the terms of the GNU General Public License as published by the Free
7// Software Foundation; either version 3 of the License, or (at your option)
8// any later version.
9//
10// This program is distributed in the hope that it will be useful, but WITHOUT
11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13// more details.
14//
15// You should have received a copy of the GNU General Public License along with
16// this program; if not, write to the Free Software Foundation, Inc., 51
17// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19#pragma once
20
0e4e4b63 21#include <Hash.hpp>
38ab9d38 22#include <hashutil.hpp>
3b6c2a5a 23#include <util/Duration.hpp>
54cbb06a 24#include <util/Fd.hpp>
de637952 25#include <util/TimePoint.hpp>
3b6c2a5a 26
ca9ec9cf 27#include <cstdint>
55043100 28#include <functional>
a179db20 29#include <optional>
2354adc2 30#include <string>
cd4e26df 31#include <utility>
213d9883
OL
32
33class Config;
34class Context;
213d9883
OL
35
36class InodeCache
37{
38public:
561be208
JR
39 // Specifies in which mode a file was hashed since the hash result does not
40 // only depend on the actual content but also on operations that were
41 // performed that affect the return value. For example, source code files are
42 // normally scanned for macros while binary files are not.
213d9883 43 enum class ContentType {
561be208
JR
44 // The file was not scanned for temporal macros.
45 raw = 0,
46 // The file was checked for temporal macros (see check_for_temporal_macros
47 // in hashutil).
48 checked_for_temporal_macros = 1,
213d9883
OL
49 };
50
3b6c2a5a
JR
51 // `min_age` specifies how old a file must be to be put in the cache. The
52 // reason for this is that there is a race condition that consists of these
53 // events:
54 //
55 // 1. A file is written with content C1, size S and timestamp (ctime/mtime) T.
56 // 2. Ccache hashes the file content and asks the inode cache to store the
c77a6558 57 // digest with a hash of S and T (and some other data) as the key.
3b6c2a5a
JR
58 // 3. The file is quickly thereafter written with content C2 without changing
59 // size S and timestamp T. The timestamp is not updated since the file
60 // writes are made within a time interval smaller than the granularity of
61 // the clock used for file system timestamps. At the time of writing, a
62 // common granularity on a Linux system is 0.004 s (250 Hz).
63 // 4. The inode cache is asked for the file digest and the inode cache
64 // delivers a digest of C1 even though the file's content is C2.
65 //
66 // To avoid the race condition, the inode cache only caches inodes whose
67 // timestamp was updated more than `min_age` ago. The default value is a
68 // conservative 2 seconds since not all file systems have subsecond
69 // resolution.
70 InodeCache(const Config& config, util::Duration min_age = util::Duration(2));
213d9883
OL
71 ~InodeCache();
72
5edcc6c3
JR
73 // Return whether it's possible to use the inode cache on the filesystem
74 // associated with `fd`.
75 static bool available(int fd);
76
213d9883 77 // Get saved hash digest and return value from a previous call to
561be208 78 // do_hash_file() in hashutil.cpp.
cd4e26df
JR
79 std::optional<std::pair<HashSourceCodeResult, Hash::Digest>>
80 get(const std::string& path, ContentType type);
213d9883 81
561be208
JR
82 // Put hash digest and return value from a successful call to do_hash_file()
83 // in hashutil.cpp.
213d9883
OL
84 //
85 // Returns true if values could be stored in the cache, false otherwise.
2292fef1 86 bool put(const std::string& path,
213d9883 87 ContentType type,
0e4e4b63 88 const Hash::Digest& file_digest,
38ab9d38 89 HashSourceCodeResult return_value);
213d9883
OL
90
91 // Unmaps the current cache and removes the mapped file from disk.
92 //
93 // Returns true on success, false otherwise.
94 bool drop();
95
96 // Returns name of the persistent file.
97 std::string get_file();
98
99 // Returns total number of cache hits.
100 //
101 // Counters are incremented in debug mode only.
102 int64_t get_hits();
103
104 // Returns total number of cache misses.
105 //
106 // Counters are incremented in debug mode only.
107 int64_t get_misses();
108
109 // Returns total number of errors.
110 //
111 // Currently only lock errors will be counted, since the counter is not
112 // accessible before the file has been successfully mapped into memory.
113 //
114 // Counters are incremented in debug mode only.
115 int64_t get_errors();
116
117private:
118 struct Bucket;
119 struct Entry;
120 struct Key;
121 struct SharedRegion;
55043100 122 using BucketHandler = std::function<void(Bucket* bucket)>;
213d9883
OL
123
124 bool mmap_file(const std::string& inode_cache_file);
0e4e4b63
JR
125
126 bool
127 hash_inode(const std::string& path, ContentType type, Hash::Digest& digest);
128
129 bool with_bucket(const Hash::Digest& key_digest,
55043100 130 const BucketHandler& bucket_handler);
0e4e4b63 131
17f00366 132 static bool create_new_file(const std::string& filename);
0e4e4b63 133
213d9883
OL
134 bool initialize();
135
136 const Config& m_config;
3b6c2a5a 137 util::Duration m_min_age;
54cbb06a 138 util::Fd m_fd;
77bf7bc3
JR
139 struct SharedRegion* m_sr = nullptr;
140 bool m_failed = false;
95e63758 141 const pid_t m_self_pid;
de637952 142 util::TimePoint m_last_fs_space_check;
213d9883 143};