]> git.ipfire.org Git - thirdparty/ccache.git/blame - src/InodeCache.hpp
chore: Clean up usage of #include in headers
[thirdparty/ccache.git] / src / InodeCache.hpp
CommitLineData
81d4e568 1// Copyright (C) 2020-2024 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>
55ee4572 25#include <util/MemoryMap.hpp>
de637952 26#include <util/TimePoint.hpp>
3b6c2a5a 27
81d4e568
JR
28#include <sys/types.h>
29
ca9ec9cf 30#include <cstdint>
55043100 31#include <functional>
a179db20 32#include <optional>
2354adc2 33#include <string>
cd4e26df 34#include <utility>
213d9883
OL
35
36class Config;
213d9883
OL
37
38class InodeCache
39{
40public:
561be208
JR
41 // Specifies in which mode a file was hashed since the hash result does not
42 // only depend on the actual content but also on operations that were
43 // performed that affect the return value. For example, source code files are
44 // normally scanned for macros while binary files are not.
213d9883 45 enum class ContentType {
561be208
JR
46 // The file was not scanned for temporal macros.
47 raw = 0,
48 // The file was checked for temporal macros (see check_for_temporal_macros
49 // in hashutil).
50 checked_for_temporal_macros = 1,
213d9883
OL
51 };
52
3b6c2a5a
JR
53 // `min_age` specifies how old a file must be to be put in the cache. The
54 // reason for this is that there is a race condition that consists of these
55 // events:
56 //
57 // 1. A file is written with content C1, size S and timestamp (ctime/mtime) T.
58 // 2. Ccache hashes the file content and asks the inode cache to store the
c77a6558 59 // digest with a hash of S and T (and some other data) as the key.
3b6c2a5a
JR
60 // 3. The file is quickly thereafter written with content C2 without changing
61 // size S and timestamp T. The timestamp is not updated since the file
62 // writes are made within a time interval smaller than the granularity of
63 // the clock used for file system timestamps. At the time of writing, a
64 // common granularity on a Linux system is 0.004 s (250 Hz).
65 // 4. The inode cache is asked for the file digest and the inode cache
66 // delivers a digest of C1 even though the file's content is C2.
67 //
68 // To avoid the race condition, the inode cache only caches inodes whose
69 // timestamp was updated more than `min_age` ago. The default value is a
70 // conservative 2 seconds since not all file systems have subsecond
71 // resolution.
72 InodeCache(const Config& config, util::Duration min_age = util::Duration(2));
213d9883
OL
73 ~InodeCache();
74
5edcc6c3
JR
75 // Return whether it's possible to use the inode cache on the filesystem
76 // associated with `fd`.
77 static bool available(int fd);
78
213d9883 79 // Get saved hash digest and return value from a previous call to
561be208 80 // do_hash_file() in hashutil.cpp.
cd4e26df
JR
81 std::optional<std::pair<HashSourceCodeResult, Hash::Digest>>
82 get(const std::string& path, ContentType type);
213d9883 83
561be208
JR
84 // Put hash digest and return value from a successful call to do_hash_file()
85 // in hashutil.cpp.
213d9883
OL
86 //
87 // Returns true if values could be stored in the cache, false otherwise.
2292fef1 88 bool put(const std::string& path,
213d9883 89 ContentType type,
0e4e4b63 90 const Hash::Digest& file_digest,
38ab9d38 91 HashSourceCodeResult return_value);
213d9883
OL
92
93 // Unmaps the current cache and removes the mapped file from disk.
94 //
95 // Returns true on success, false otherwise.
96 bool drop();
97
98 // Returns name of the persistent file.
99 std::string get_file();
100
101 // Returns total number of cache hits.
102 //
103 // Counters are incremented in debug mode only.
104 int64_t get_hits();
105
106 // Returns total number of cache misses.
107 //
108 // Counters are incremented in debug mode only.
109 int64_t get_misses();
110
111 // Returns total number of errors.
112 //
113 // Currently only lock errors will be counted, since the counter is not
114 // accessible before the file has been successfully mapped into memory.
115 //
116 // Counters are incremented in debug mode only.
117 int64_t get_errors();
118
119private:
120 struct Bucket;
121 struct Entry;
122 struct Key;
123 struct SharedRegion;
55043100 124 using BucketHandler = std::function<void(Bucket* bucket)>;
213d9883
OL
125
126 bool mmap_file(const std::string& inode_cache_file);
0e4e4b63
JR
127
128 bool
129 hash_inode(const std::string& path, ContentType type, Hash::Digest& digest);
130
131 bool with_bucket(const Hash::Digest& key_digest,
55043100 132 const BucketHandler& bucket_handler);
0e4e4b63 133
17f00366 134 static bool create_new_file(const std::string& filename);
0e4e4b63 135
213d9883
OL
136 bool initialize();
137
138 const Config& m_config;
3b6c2a5a 139 util::Duration m_min_age;
54cbb06a 140 util::Fd m_fd;
77bf7bc3
JR
141 struct SharedRegion* m_sr = nullptr;
142 bool m_failed = false;
95e63758 143 const pid_t m_self_pid;
de637952 144 util::TimePoint m_last_fs_space_check;
55ee4572 145 util::MemoryMap m_map;
213d9883 146};