| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/catalog_diff_tool.h |
| Date: | 2025-11-02 02:35:35 |
| 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 | 56 | 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 | 56 | : repo_path_(repo_path) | |
| 41 | 56 | , old_root_hash_(old_root_hash) | |
| 42 | 56 | , new_root_hash_(new_root_hash) | |
| 43 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , temp_dir_prefix_(temp_dir_prefix) |
| 44 | 56 | , download_manager_(download_manager) | |
| 45 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , cache_dir_(cache_dir) |
| 46 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , old_raii_temp_dir_() |
| 47 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , new_raii_temp_dir_() |
| 48 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , old_catalog_mgr_() |
| 49 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
56 | , new_catalog_mgr_() |
| 50 |
2/4✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 56 times.
✗ Branch 6 not taken.
|
168 | , needs_setup_(true) { } |
| 51 | |||
| 52 | 112 | 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 |