GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/receiver/catalog_merge_tool.h
Date: 2026-08-30 02:40:36
Exec Total Coverage
Lines: 19 19 100.0%
Branches: 11 20 55.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_RECEIVER_CATALOG_MERGE_TOOL_H_
6 #define CVMFS_RECEIVER_CATALOG_MERGE_TOOL_H_
7
8 #include <memory>
9 #include <string>
10
11 #include "catalog_diff_tool.h"
12 #include "file_chunk.h"
13 #include "params.h"
14 #include "shortstring.h"
15 #include "statistics.h"
16
17 namespace catalog {
18 class WritableCatalogManager;
19 }
20
21 namespace download {
22 class DownloadManager;
23 }
24
25 namespace manifest {
26 class Manifest;
27 }
28
29 namespace shash {
30 struct Any;
31 }
32
33 namespace receiver {
34
35 // Lease paths are slash-free and relative to the repository root. In
36 // particular, map "/" from mountless root ingests to the empty root path.
37 245 inline PathString NormalizeLeasePath(const PathString &lease_path) {
38
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 const std::string path = lease_path.ToString();
39 245 const size_t start = path.find_first_not_of('/');
40
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 98 times.
245 if (start == std::string::npos) {
41 // Empty or all slashes (e.g. "" or "/"): the repository root.
42
2/4
✓ Branch 2 taken 147 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 147 times.
✗ Branch 6 not taken.
147 return PathString("");
43 }
44 98 const size_t end = path.find_last_not_of('/');
45
2/4
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 98 times.
✗ Branch 5 not taken.
196 return PathString(path.substr(start, end - start + 1));
46 245 }
47
48 template<typename RwCatalogMgr, typename RoCatalogMgr>
49 class CatalogMergeTool : public CatalogDiffTool<RoCatalogMgr> {
50 public:
51 CatalogMergeTool(RoCatalogMgr *old_catalog_mgr, RoCatalogMgr *new_catalog_mgr,
52 RwCatalogMgr *output_catalog_mgr,
53 const PathString &lease_path,
54 const std::string &temp_dir_prefix,
55 manifest::Manifest *manifest, perf::Statistics *statistics)
56 : CatalogDiffTool<RoCatalogMgr>(old_catalog_mgr, new_catalog_mgr)
57 , repo_path_("")
58 , cache_dir_("")
59 , lease_path_(NormalizeLeasePath(lease_path))
60 , temp_dir_prefix_(temp_dir_prefix)
61 , download_manager_(NULL)
62 , manifest_(manifest)
63 , output_catalog_mgr_(output_catalog_mgr)
64 , needs_setup_(false)
65 , statistics_(statistics)
66 , counters_(nullptr) { }
67
68 CatalogMergeTool(RoCatalogMgr *old_catalog_mgr, RoCatalogMgr *new_catalog_mgr,
69 const std::string &repo_path, const PathString &lease_path,
70 const std::string &temp_dir_prefix,
71 download::DownloadManager *download_manager,
72 manifest::Manifest *manifest, perf::Statistics *statistics)
73 : CatalogDiffTool<RoCatalogMgr>(old_catalog_mgr, new_catalog_mgr)
74 , repo_path_(repo_path)
75 , cache_dir_("")
76 , lease_path_(NormalizeLeasePath(lease_path))
77 , temp_dir_prefix_(temp_dir_prefix)
78 , download_manager_(download_manager)
79 , manifest_(manifest)
80 , needs_setup_(true)
81 , statistics_(statistics)
82 , counters_(nullptr) { }
83
84 245 CatalogMergeTool(const std::string &repo_path,
85 const shash::Any &old_root_hash,
86 const shash::Any &new_root_hash,
87 const PathString &lease_path,
88 const std::string &temp_dir_prefix,
89 download::DownloadManager *download_manager,
90 manifest::Manifest *manifest,
91 perf::Statistics *statistics,
92 const std::string &cache_dir)
93 : CatalogDiffTool<RoCatalogMgr>(repo_path, old_root_hash, new_root_hash,
94 temp_dir_prefix, download_manager,
95 cache_dir)
96 245 , repo_path_(repo_path)
97
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 , cache_dir_(cache_dir)
98
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 , lease_path_(NormalizeLeasePath(lease_path))
99
1/2
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
245 , temp_dir_prefix_(temp_dir_prefix)
100 245 , download_manager_(download_manager)
101 245 , manifest_(manifest)
102 245 , needs_setup_(true)
103 245 , statistics_(statistics)
104
1/2
✓ Branch 2 taken 245 times.
✗ Branch 3 not taken.
490 , counters_(nullptr) { }
105
106 490 virtual ~CatalogMergeTool() { }
107
108 bool Run(const Params &params, std::string *new_manifest_path,
109 shash::Any *new_manifest_hash, uint64_t *final_rev);
110
111 protected:
112 virtual bool IsIgnoredPath(const PathString &path);
113 virtual bool IsReportablePath(const PathString &path);
114
115 virtual bool ReportAddition(const PathString &path,
116 const catalog::DirectoryEntry &entry,
117 const XattrList &xattrs,
118 const FileChunkList &chunks);
119 virtual void ReportRemoval(const PathString &path,
120 const catalog::DirectoryEntry &entry);
121 virtual bool ReportModification(const PathString &path,
122 const catalog::DirectoryEntry &old_entry,
123 const catalog::DirectoryEntry &new_entry,
124 const XattrList &xattrs,
125 const FileChunkList &chunks);
126
127 private:
128 bool CreateNewManifest(std::string *new_manifest_path);
129
130 // Create missing, non-reportable lease ancestors before the scoped diff.
131 // Their metadata is receiver-controlled; false indicates an invalid tree.
132
133 bool CreateMissingAncestorDirs();
134
135 std::string repo_path_;
136 const std::string cache_dir_; // path if local cache is used, otherwise empty
137
138 PathString lease_path_;
139 std::string temp_dir_prefix_;
140
141 download::DownloadManager *download_manager_;
142
143 manifest::Manifest *manifest_;
144
145 std::unique_ptr<RwCatalogMgr> output_catalog_mgr_;
146
147 const bool needs_setup_;
148
149 perf::Statistics *statistics_;
150 std::unique_ptr<perf::FsCounters> counters_;
151 };
152
153 } // namespace receiver
154
155 #include "catalog_merge_tool_impl.h"
156
157 #endif // CVMFS_RECEIVER_CATALOG_MERGE_TOOL_H_
158