Optional attributes:
+* *layout*: How to store file under the cache directory. Available values:
++
+--
+* *flat*: Store all files directly under the cache directory.
+* *subdirs*: Store files in 256 subdirectories of the cache directory.
+--
++
+The default is *subdirs*.
* *umask*: This attribute (an octal integer) overrides the umask to use for
files and directories in the cache directory.
* *update-mtime*: If *true*, update the modification time (mtime) of cache
nonstd::expected<bool, Failure> remove(const Digest& key) override;
private:
+ enum class Layout { flat, subdirs };
+
const std::string m_dir;
nonstd::optional<mode_t> m_umask;
bool m_update_mtime = false;
+ Layout m_layout = Layout::subdirs;
std::string get_entry_path(const Digest& key) const;
};
}
for (const auto& attr : params.attributes) {
- if (attr.key == "umask") {
+ if (attr.key == "layout") {
+ if (attr.value == "flat") {
+ m_layout = Layout::flat;
+ } else if (attr.value == "subdirs") {
+ m_layout = Layout::subdirs;
+ } else {
+ LOG("Unknown layout: {}", attr.value);
+ }
+ } else if (attr.key == "umask") {
m_umask =
util::value_or_throw<core::Fatal>(util::parse_umask(attr.value));
} else if (attr.key == "update-mtime") {
std::string
FileStorageBackend::get_entry_path(const Digest& key) const
{
- const auto key_string = key.to_string();
- const uint8_t digits = 2;
- return FMT("{}/{:.{}}/{}", m_dir, key_string, digits, &key_string[digits]);
+ switch (m_layout) {
+ case Layout::flat:
+ return FMT("{}/{}", m_dir, key.to_string());
+
+ case Layout::subdirs: {
+ const auto key_str = key.to_string();
+ const uint8_t digits = 2;
+ ASSERT(key_str.length() > digits);
+ return FMT("{}/{:.{}}/{}", m_dir, key_str, digits, &key_str[digits]);
+ }
+ }
+
+ ASSERT(false);
}
} // namespace
SUITE_secondary_file() {
# -------------------------------------------------------------------------
- TEST "Base case"
+ TEST "Subdirs layout"
$CCACHE_COMPILE -c test.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache miss' 1
expect_stat 'files in cache' 2
expect_exists secondary/CACHEDIR.TAG
+ subdirs=$(find secondary -type d | wc -l)
+ if [ "${subdirs}" -lt 2 ]; then # "secondary" itself counts as one
+ test_failed "Expected subdirectories in secondary"
+ fi
+ expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
+
+ $CCACHE_COMPILE -c test.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 2
+ expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
+
+ $CCACHE -C >/dev/null
+ expect_stat 'files in cache' 0
+ expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
+
+ $CCACHE_COMPILE -c test.c
+ expect_stat 'cache hit (direct)' 2
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 2 # fetched from secondary
+ expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
+
+ # -------------------------------------------------------------------------
+ TEST "Flat layout"
+
+ CCACHE_SECONDARY_STORAGE+="|layout=flat"
+
+ $CCACHE_COMPILE -c test.c
+ expect_stat 'cache hit (direct)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 2
+ expect_exists secondary/CACHEDIR.TAG
+ subdirs=$(find secondary -type d | wc -l)
+ if [ "${subdirs}" -ne 1 ]; then # "secondary" itself counts as one
+ test_failed "Expected no subdirectories in secondary"
+ fi
expect_file_count 3 '*' secondary # CACHEDIR.TAG + result + manifest
$CCACHE_COMPILE -c test.c