diff options
Diffstat (limited to 'src/buildtool/execution_api/local/local_cas.hpp')
-rw-r--r-- | src/buildtool/execution_api/local/local_cas.hpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/buildtool/execution_api/local/local_cas.hpp b/src/buildtool/execution_api/local/local_cas.hpp new file mode 100644 index 00000000..4a28e796 --- /dev/null +++ b/src/buildtool/execution_api/local/local_cas.hpp @@ -0,0 +1,103 @@ +#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_HPP +#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_HPP + +#include <sstream> +#include <thread> + +#include "src/buildtool/common/artifact.hpp" +#include "src/buildtool/execution_api/bazel_msg/bazel_blob.hpp" +#include "src/buildtool/execution_api/common/execution_common.hpp" +#include "src/buildtool/execution_api/local/config.hpp" +#include "src/buildtool/execution_api/local/file_storage.hpp" +#include "src/buildtool/file_system/file_system_manager.hpp" +#include "src/buildtool/logging/logger.hpp" + +template <ObjectType kType = ObjectType::File> +class LocalCAS { + public: + LocalCAS() noexcept = default; + + explicit LocalCAS(std::filesystem::path cache_root) noexcept + : cache_root_{std::move(cache_root)} {} + + LocalCAS(LocalCAS const&) = delete; + LocalCAS(LocalCAS&&) = delete; + auto operator=(LocalCAS const&) -> LocalCAS& = delete; + auto operator=(LocalCAS &&) -> LocalCAS& = delete; + ~LocalCAS() noexcept = default; + + [[nodiscard]] auto StoreBlobFromBytes(std::string const& bytes) + const noexcept -> std::optional<bazel_re::Digest> { + return StoreBlob(bytes); + } + + [[nodiscard]] auto StoreBlobFromFile(std::filesystem::path const& file_path) + const noexcept -> std::optional<bazel_re::Digest> { + return StoreBlob(file_path); + } + + [[nodiscard]] auto BlobPath(bazel_re::Digest const& digest) const noexcept + -> std::optional<std::filesystem::path> { + auto blob_path = file_store_.GetPath(digest.hash()); + if (FileSystemManager::IsFile(blob_path)) { + return blob_path; + } + logger_.Emit(LogLevel::Debug, "Blob not found {}", digest.hash()); + return std::nullopt; + } + + private: + static constexpr char kSuffix = ToChar(kType); + Logger logger_{std::string{"LocalCAS"} + kSuffix}; + std::filesystem::path const cache_root_{ + LocalExecutionConfig::GetCacheDir()}; + FileStorage<kType> file_store_{cache_root_ / + (std::string{"cas"} + kSuffix)}; + + [[nodiscard]] static auto CreateDigest(std::string const& bytes) noexcept + -> std::optional<bazel_re::Digest> { + return ArtifactDigest::Create(bytes); + } + + [[nodiscard]] static auto CreateDigest( + std::filesystem::path const& file_path) noexcept + -> std::optional<bazel_re::Digest> { + auto const bytes = FileSystemManager::ReadFile(file_path); + if (bytes.has_value()) { + return ArtifactDigest::Create(*bytes); + } + return std::nullopt; + } + + /// \brief Store blob from bytes to storage. + [[nodiscard]] auto StoreBlobData(std::string const& blob_id, + std::string const& bytes) const noexcept + -> bool { + return file_store_.AddFromBytes(blob_id, bytes); + } + + /// \brief Store blob from file path to storage. + [[nodiscard]] auto StoreBlobData( + std::string const& blob_id, + std::filesystem::path const& file_path) const noexcept -> bool { + return file_store_.AddFromFile(blob_id, file_path); + } + + /// \brief Store blob from unspecified data to storage. + template <class T> + [[nodiscard]] auto StoreBlob(T const& data) const noexcept + -> std::optional<bazel_re::Digest> { + auto digest = CreateDigest(data); + if (digest) { + if (StoreBlobData(digest->hash(), data)) { + return digest; + } + logger_.Emit( + LogLevel::Debug, "Failed to store blob {}.", digest->hash()); + } + logger_.Emit(LogLevel::Debug, "Failed to create digest."); + return std::nullopt; + } +}; + +#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_HPP |