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 |