GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/catalog_diff_tool.h
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 13 24 54.2%
Branches: 8 38 21.1%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_CATALOG_DIFF_TOOL_H_
6 #define CVMFS_CATALOG_DIFF_TOOL_H_
7
8 #include <string>
9
10 #include "directory_entry.h"
11 #include "file_chunk.h"
12 #include "shortstring.h"
13 #include "statistics.h"
14 #include "util/pointer.h"
15 #include "util/raii_temp_dir.h"
16 #include "xattr.h"
17
18 namespace download {
19 class DownloadManager;
20 }
21
22 template<typename RoCatalogMgr>
23 class CatalogDiffTool {
24 public:
25 CatalogDiffTool(RoCatalogMgr *old_catalog_mgr, RoCatalogMgr *new_catalog_mgr)
26 : repo_path_("")
27 , temp_dir_prefix_("")
28 , download_manager_(NULL)
29 , cache_dir_("")
30 , old_catalog_mgr_(old_catalog_mgr)
31 , new_catalog_mgr_(new_catalog_mgr)
32 , needs_setup_(false) { }
33
34 98 CatalogDiffTool(const std::string &repo_path,
35 const shash::Any &old_root_hash,
36 const shash::Any &new_root_hash,
37 const std::string &temp_dir_prefix,
38 download::DownloadManager *download_manager,
39 const std::string &cache_dir = "")
40 98 : repo_path_(repo_path)
41 98 , old_root_hash_(old_root_hash)
42 98 , new_root_hash_(new_root_hash)
43
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , temp_dir_prefix_(temp_dir_prefix)
44 98 , download_manager_(download_manager)
45
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , cache_dir_(cache_dir)
46
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , old_raii_temp_dir_()
47
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , new_raii_temp_dir_()
48
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , old_catalog_mgr_()
49
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 , new_catalog_mgr_()
50
2/4
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 98 times.
✗ Branch 6 not taken.
294 , needs_setup_(true) { }
51
52 196 virtual ~CatalogDiffTool() { }
53
54 bool Init();
55
56 bool Run(const PathString &path);
57
58 protected:
59 /**
60 * Check if a path (and, by implication, any subpath) should be
61 * ignored and not considered for comparison purposes.
62 *
63 * This can be used to avoid unnecessary work by avoiding recursion
64 * into paths that will not be of interest (e.g. paths that are
65 * neither above nor within the lease path, when using a gateway).
66 */
67 virtual bool IsIgnoredPath(const PathString & /* path */) { return false; }
68
69 /**
70 * Check if a difference found on a path should be reported via
71 * ReportAddition(), ReportRemoval(), or ReportModification().
72 *
73 * This can be used to filter out differences that are not of
74 * interest (e.g. paths that are not within the lease path, when
75 * using a gateway).
76 *
77 * Note that an ignored path must necessarily be a non-reportable
78 * path, since an ignored path will never even be compared (and so
79 * can never be reported upon). However, there do exist paths that
80 * are neither ignored nor reportable: when using a gateway, a
81 * parent of the lease path is not reportable (since it is not
82 * within the lease path) but must not be ignored (since we need to
83 * recurse into the parent path in order to reach the lease path).
84 *
85 * As a concrete example, with a lease path of /foo/bar:
86 *
87 * /foo <- not ignored, not reportable
88 * /foo/bar <- not ignored reportable
89 * /foo/bar/thing <- not ignored reportable
90 * /foo/baz <- ignored (and therefore not reportable)
91 */
92 virtual bool IsReportablePath(const PathString & /* path */) { return true; }
93
94 // Note that addition and modification can return false to indicate that
95 // the recursion stops. In the merge tool, this happens at nested catalog
96 // transition points:
97 // - For a new directory that is a nested catalog, we don't need to recurse
98 // further but just install that nested catalog in the parent
99 // - When a nested catalog is replaced, we likewise do not need to recurse
100 // further into the new nested catalog tree.
101
102 virtual bool ReportAddition(const PathString &path,
103 const catalog::DirectoryEntry &entry,
104 const XattrList &xattrs,
105 const FileChunkList &chunks) = 0;
106 virtual void ReportRemoval(const PathString &path,
107 const catalog::DirectoryEntry &entry) = 0;
108 virtual bool ReportModification(const PathString &path,
109 const catalog::DirectoryEntry &old_entry,
110 const catalog::DirectoryEntry &new_entry,
111 const XattrList &xattrs,
112 const FileChunkList &chunks) = 0;
113
114 const catalog::Catalog *GetOldCatalog() const {
115 return old_catalog_mgr_->GetRootCatalog();
116 }
117 const catalog::Catalog *GetNewCatalog() const {
118 return new_catalog_mgr_->GetRootCatalog();
119 }
120 RoCatalogMgr *GetOldCatalogMgr() { return old_catalog_mgr_.weak_ref(); }
121 RoCatalogMgr *GetNewCatalogMgr() { return new_catalog_mgr_.weak_ref(); }
122
123 private:
124 RoCatalogMgr *OpenCatalogManager(const std::string &repo_path,
125 const std::string &temp_dir,
126 const shash::Any &root_hash,
127 download::DownloadManager *download_manager,
128 perf::Statistics *stats,
129 const std::string &cache_dir);
130
131 void DiffRec(const PathString &path);
132
133 std::string repo_path_;
134 shash::Any old_root_hash_;
135 shash::Any new_root_hash_;
136 std::string temp_dir_prefix_;
137
138 download::DownloadManager *download_manager_;
139 const std::string cache_dir_; // path if local caching of catalogs
140
141 perf::Statistics stats_old_;
142 perf::Statistics stats_new_;
143
144 UniquePtr<RaiiTempDir> old_raii_temp_dir_;
145 UniquePtr<RaiiTempDir> new_raii_temp_dir_;
146
147 UniquePtr<RoCatalogMgr> old_catalog_mgr_;
148 UniquePtr<RoCatalogMgr> new_catalog_mgr_;
149
150 const bool needs_setup_;
151 };
152
153 #include "catalog_diff_tool_impl.h"
154
155 #endif // CVMFS_CATALOG_DIFF_TOOL_H_
156