diff options
-rw-r--r-- | src/buildtool/build_engine/target_map/target_cache.cpp | 4 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_cache.hpp | 5 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/TARGETS | 10 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/config.hpp | 74 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_ac.hpp | 2 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_action.cpp | 2 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_cas.hpp | 2 |
7 files changed, 76 insertions, 23 deletions
diff --git a/src/buildtool/build_engine/target_map/target_cache.cpp b/src/buildtool/build_engine/target_map/target_cache.cpp index 727b7404..e08697db 100644 --- a/src/buildtool/build_engine/target_map/target_cache.cpp +++ b/src/buildtool/build_engine/target_map/target_cache.cpp @@ -94,8 +94,8 @@ auto TargetCache::DownloadKnownArtifacts( #endif } -auto TargetCache::ComputeCacheDir() -> std::filesystem::path { - return LocalExecutionConfig::TargetCacheDir() / ExecutionBackendId(); +auto TargetCache::ComputeCacheDir(int index) -> std::filesystem::path { + return LocalExecutionConfig::TargetCacheDir(index) / ExecutionBackendId(); } auto TargetCache::ExecutionBackendId() -> std::string { diff --git a/src/buildtool/build_engine/target_map/target_cache.hpp b/src/buildtool/build_engine/target_map/target_cache.hpp index ef25c058..6ea29f31 100644 --- a/src/buildtool/build_engine/target_map/target_cache.hpp +++ b/src/buildtool/build_engine/target_map/target_cache.hpp @@ -75,7 +75,7 @@ class TargetCache { FileStorage<ObjectType::File, StoreMode::LastWins, /*kSetEpochTime=*/false> - file_store_{ComputeCacheDir()}; + file_store_{ComputeCacheDir(0)}; #ifndef BOOTSTRAP_BUILD_TOOL IExecutionApi* local_api_{}; IExecutionApi* remote_api_{}; @@ -86,7 +86,8 @@ class TargetCache { [[nodiscard]] static auto CAS() noexcept -> LocalCAS<ObjectType::File>& { return LocalCAS<ObjectType::File>::Instance(); } - [[nodiscard]] static auto ComputeCacheDir() -> std::filesystem::path; + [[nodiscard]] static auto ComputeCacheDir(int index) + -> std::filesystem::path; [[nodiscard]] static auto ExecutionBackendId() -> std::string; }; diff --git a/src/buildtool/execution_api/local/TARGETS b/src/buildtool/execution_api/local/TARGETS index c7311e11..d07b06a1 100644 --- a/src/buildtool/execution_api/local/TARGETS +++ b/src/buildtool/execution_api/local/TARGETS @@ -3,9 +3,15 @@ , "name": ["config"] , "hdrs": ["config.hpp"] , "deps": - [ ["src/buildtool/compatibility", "compatibility"] - , ["src/buildtool/logging", "logging"] + [ ["@", "fmt", "", "fmt"] + , ["@", "json", "", "json"] + , ["@", "gsl-lite", "", "gsl-lite"] + , ["src/buildtool/common", "common"] + , ["src/buildtool/compatibility", "compatibility"] , ["src/buildtool/file_system", "file_system_manager"] + , ["src/buildtool/file_system", "object_type"] + , ["src/buildtool/logging", "log_level"] + , ["src/buildtool/logging", "logging"] ] , "stage": ["src", "buildtool", "execution_api", "local"] } diff --git a/src/buildtool/execution_api/local/config.hpp b/src/buildtool/execution_api/local/config.hpp index 1b129053..409c07ac 100644 --- a/src/buildtool/execution_api/local/config.hpp +++ b/src/buildtool/execution_api/local/config.hpp @@ -28,8 +28,13 @@ #include <string> #include <vector> +#include <gsl-lite/gsl-lite.hpp> + +#include "src/buildtool/common/artifact_digest.hpp" #include "src/buildtool/compatibility/compatibility.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" +#include "src/buildtool/file_system/object_type.hpp" +#include "src/buildtool/logging/log_level.hpp" #include "src/buildtool/logging/logger.hpp" /// \brief Store global build system configuration. @@ -42,11 +47,16 @@ class LocalExecutionConfig { // then build_root will be set to PATH. std::filesystem::path build_root{}; - // cache_root points to one of the following - // build_root/protocol-dependent/{git-sha1,compatible-sha256} + // cache_root points to the root of the cache dirs. + std::filesystem::path cache_root{}; + + // cache_root_generations holds root directories for all cache + // generations (default: two generations). The latest generation points + // to one the following directories: + // build_root/protocol-dependent/generation-0/{git-sha1,compatible-sha256} // git-sha1 is the current default. If the user passes the flag // --compatible, then the subfolder compatible_sha256 is used - std::filesystem::path cache_root{}; + std::vector<std::filesystem::path> cache_root_generations{"", ""}; // Launcher to be prepended to action's command before executed. // Default: ["env", "--"] @@ -70,8 +80,16 @@ class LocalExecutionConfig { return false; } Data().build_root = dir; - Data().cache_root = ""; // in case we re-set build_root, we are sure - // that the cache path is recomputed as well + // In case we re-set build_root, we are sure that the cache roots are + // recomputed as well. + Data().cache_root = std::filesystem::path{}; + Data().cache_root_generations = + std::vector(NumGenerations(), std::filesystem::path{}); + // Pre-initialize cache roots to avoid race condition during lazy + // initialization by multiple threads. + for (int i = 0; i < NumGenerations(); ++i) { + [[maybe_unused]] auto root = CacheRoot(i); + } return true; } @@ -88,6 +106,17 @@ class LocalExecutionConfig { return true; } + /// \brief Specifies the number of cache generations. + static auto SetNumGenerations(int num_generations) noexcept -> void { + gsl_ExpectsAudit(num_generations > 0); + Data().cache_root_generations = + std::vector(num_generations, std::filesystem::path{}); + } + + [[nodiscard]] static auto NumGenerations() noexcept -> int { + return Data().cache_root_generations.size(); + } + /// \brief User directory. [[nodiscard]] static auto GetUserDir() noexcept -> std::filesystem::path { return GetUserHome() / ".cache" / "just"; @@ -105,15 +134,32 @@ class LocalExecutionConfig { [[nodiscard]] static auto CacheRoot() noexcept -> std::filesystem::path { auto& cache_root = Data().cache_root; if (cache_root.empty()) { - cache_root = UpdatePathForCompatibility( - BuildRoot() / "protocol-dependent" / "generation-0"); + cache_root = BuildRoot() / "protocol-dependent"; } return cache_root; } + [[nodiscard]] static auto CacheRoot(int index) noexcept + -> std::filesystem::path { + gsl_ExpectsAudit(index >= 0 and + index < Data().cache_root_generations.size()); + auto& cache_root = Data().cache_root_generations[index]; + if (cache_root.empty()) { + auto generation = + std::string{"generation-"} + std::to_string(index); + cache_root = CacheRoot() / generation; + } + return cache_root; + } + + [[nodiscard]] static auto CacheRootDir(int index) noexcept + -> std::filesystem::path { + return UpdatePathForCompatibility(CacheRoot(index)); + } + // CAS directory based on the type of the file. template <ObjectType kType> - [[nodiscard]] static inline auto CASDir() noexcept + [[nodiscard]] static inline auto CASDir(int index) noexcept -> std::filesystem::path { char t = ToChar(kType); if constexpr (kType == ObjectType::Tree) { @@ -121,20 +167,20 @@ class LocalExecutionConfig { t = ToChar(ObjectType::File); } } - static const std::string kSuffix = std::string{"cas"} + t; - return CacheRoot() / kSuffix; + static auto const kSuffix = std::string{"cas"} + t; + return CacheRootDir(index) / kSuffix; } /// \brief Action cache directory - [[nodiscard]] static auto ActionCacheDir() noexcept + [[nodiscard]] static auto ActionCacheDir(int index) noexcept -> std::filesystem::path { - return CacheRoot() / "ac"; + return CacheRootDir(index) / "ac"; } /// \brief Target cache directory - [[nodiscard]] static auto TargetCacheDir() noexcept + [[nodiscard]] static auto TargetCacheDir(int index) noexcept -> std::filesystem::path { - return CacheRoot() / "tc"; + return CacheRootDir(index) / "tc"; } [[nodiscard]] static auto GetLauncher() noexcept diff --git a/src/buildtool/execution_api/local/local_ac.hpp b/src/buildtool/execution_api/local/local_ac.hpp index 7800d16f..03945d16 100644 --- a/src/buildtool/execution_api/local/local_ac.hpp +++ b/src/buildtool/execution_api/local/local_ac.hpp @@ -87,7 +87,7 @@ class LocalAC { Logger logger_{"LocalAC"}; gsl::not_null<LocalCAS<ObjectType::File>*> cas_; FileStorage<ObjectType::File, kStoreMode, /*kSetEpochTime=*/false> - file_store_{LocalExecutionConfig::ActionCacheDir()}; + file_store_{LocalExecutionConfig::ActionCacheDir(0)}; }; #endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_AC_HPP diff --git a/src/buildtool/execution_api/local/local_action.cpp b/src/buildtool/execution_api/local/local_action.cpp index 19842f9c..4d08f7fe 100644 --- a/src/buildtool/execution_api/local/local_action.cpp +++ b/src/buildtool/execution_api/local/local_action.cpp @@ -94,7 +94,7 @@ auto LocalAction::Execute(Logger const* logger) noexcept auto LocalAction::Run(bazel_re::Digest const& action_id) const noexcept -> std::optional<Output> { auto exec_path = - CreateUniquePath(LocalExecutionConfig::CacheRoot() / "exec_root" / + CreateUniquePath(LocalExecutionConfig::CacheRootDir(0) / "exec_root" / NativeSupport::Unprefix(action_id.hash())); if (not exec_path) { diff --git a/src/buildtool/execution_api/local/local_cas.hpp b/src/buildtool/execution_api/local/local_cas.hpp index 82716ffe..2f181ca8 100644 --- a/src/buildtool/execution_api/local/local_cas.hpp +++ b/src/buildtool/execution_api/local/local_cas.hpp @@ -72,7 +72,7 @@ class LocalCAS { Logger logger_{std::string{"LocalCAS"} + ToChar(kType)}; FileStorage<kStorageType, StoreMode::FirstWins, /*kSetEpochTime=*/true> - file_store_{LocalExecutionConfig::CASDir<kType>()}; + file_store_{LocalExecutionConfig::CASDir<kType>(0)}; [[nodiscard]] static auto CreateDigest(std::string const& bytes) noexcept -> std::optional<bazel_re::Digest> { |