Line |
Branch |
Exec |
Source |
1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
|
6 |
|
|
#include <cassert> |
7 |
|
|
#include <string> |
8 |
|
|
|
9 |
|
|
#include "catalog_counters.h" |
10 |
|
|
#include "catalog_diff_tool.h" |
11 |
|
|
#include "catalog_mgr_ro.h" |
12 |
|
|
#include "crypto/hash.h" |
13 |
|
|
#include "file_chunk.h" |
14 |
|
|
#include "history_sqlite.h" |
15 |
|
|
#include "publish/except.h" |
16 |
|
|
#include "publish/repository.h" |
17 |
|
|
#include "shortstring.h" |
18 |
|
|
#include "statistics.h" |
19 |
|
|
#include "xattr.h" |
20 |
|
|
|
21 |
|
|
namespace { |
22 |
|
|
|
23 |
|
✗ |
static history::History::Tag GetTag(const std::string &tag_name, |
24 |
|
|
const history::History &history) { |
25 |
|
✗ |
assert(!tag_name.empty()); |
26 |
|
|
|
27 |
|
✗ |
history::History::Tag tag; |
28 |
|
|
|
29 |
|
✗ |
if (tag_name[0] == publish::Repository::kRawHashSymbol) { |
30 |
|
✗ |
tag.name = tag_name.substr(1); |
31 |
|
✗ |
tag.root_hash = shash::MkFromHexPtr(shash::HexPtr(tag.name), |
32 |
|
|
shash::kSuffixCatalog); |
33 |
|
|
} else { |
34 |
|
✗ |
const bool retval = history.GetByName(tag_name, &tag); |
35 |
|
✗ |
if (!retval) |
36 |
|
✗ |
throw publish::EPublish("unknown repository tag name: " + tag_name); |
37 |
|
|
} |
38 |
|
|
|
39 |
|
✗ |
return tag; |
40 |
|
|
} |
41 |
|
|
|
42 |
|
|
|
43 |
|
|
class DiffForwarder : public CatalogDiffTool<catalog::SimpleCatalogManager> { |
44 |
|
|
private: |
45 |
|
|
publish::DiffListener *listener_; |
46 |
|
|
|
47 |
|
|
public: |
48 |
|
✗ |
DiffForwarder(catalog::SimpleCatalogManager *old_mgr, |
49 |
|
|
catalog::SimpleCatalogManager *new_mgr, |
50 |
|
|
publish::DiffListener *listener) |
51 |
|
✗ |
: CatalogDiffTool<catalog::SimpleCatalogManager>(old_mgr, new_mgr) |
52 |
|
✗ |
, listener_(listener) { } |
53 |
|
✗ |
virtual ~DiffForwarder() { } |
54 |
|
|
|
55 |
|
✗ |
virtual bool ReportAddition(const PathString &path, |
56 |
|
|
const catalog::DirectoryEntry &entry, |
57 |
|
|
const XattrList & /* xattrs */, |
58 |
|
|
const FileChunkList & /* chunks */) { |
59 |
|
✗ |
listener_->OnAdd(path.ToString(), entry); |
60 |
|
✗ |
return true; |
61 |
|
|
} |
62 |
|
|
|
63 |
|
✗ |
virtual void ReportRemoval(const PathString &path, |
64 |
|
|
const catalog::DirectoryEntry &entry) { |
65 |
|
✗ |
listener_->OnRemove(path.ToString(), entry); |
66 |
|
|
} |
67 |
|
|
|
68 |
|
✗ |
virtual bool ReportModification(const PathString &path, |
69 |
|
|
const catalog::DirectoryEntry &old_entry, |
70 |
|
|
const catalog::DirectoryEntry &new_entry, |
71 |
|
|
const XattrList & /*xattrs */, |
72 |
|
|
const FileChunkList & /* chunks */) { |
73 |
|
✗ |
listener_->OnModify(path.ToString(), old_entry, new_entry); |
74 |
|
✗ |
return true; |
75 |
|
|
} |
76 |
|
|
}; // class DiffForwarder |
77 |
|
|
|
78 |
|
|
} // anonymous namespace |
79 |
|
|
|
80 |
|
|
namespace publish { |
81 |
|
|
|
82 |
|
✗ |
void Repository::Diff(const std::string &from, const std::string &to, |
83 |
|
|
DiffListener *diff_listener) { |
84 |
|
✗ |
const history::History::Tag from_tag = GetTag(from, *history_); |
85 |
|
✗ |
const history::History::Tag to_tag = GetTag(to, *history_); |
86 |
|
✗ |
diff_listener->OnInit(from_tag, to_tag); |
87 |
|
|
|
88 |
|
✗ |
perf::Statistics stats_from; |
89 |
|
|
catalog::SimpleCatalogManager *mgr_from = new catalog::SimpleCatalogManager( |
90 |
|
|
from_tag.root_hash, |
91 |
|
✗ |
settings_.url(), |
92 |
|
✗ |
settings_.tmp_dir(), |
93 |
|
|
download_mgr_, |
94 |
|
|
&stats_from, |
95 |
|
✗ |
true /* manage_catalog_files */); |
96 |
|
✗ |
mgr_from->Init(); |
97 |
|
|
|
98 |
|
✗ |
perf::Statistics stats_to; |
99 |
|
|
catalog::SimpleCatalogManager *mgr_to = new catalog::SimpleCatalogManager( |
100 |
|
|
to_tag.root_hash, |
101 |
|
✗ |
settings_.url(), |
102 |
|
✗ |
settings_.tmp_dir(), |
103 |
|
|
download_mgr_, |
104 |
|
|
&stats_to, |
105 |
|
✗ |
true /* manage_catalog_files */); |
106 |
|
✗ |
mgr_to->Init(); |
107 |
|
|
|
108 |
|
|
const catalog::Counters counters_from = mgr_from->GetRootCatalog() |
109 |
|
✗ |
->GetCounters(); |
110 |
|
✗ |
const catalog::Counters counters_to = mgr_to->GetRootCatalog()->GetCounters(); |
111 |
|
✗ |
diff_listener->OnStats(catalog::Counters::Diff(counters_from, counters_to)); |
112 |
|
|
|
113 |
|
|
// DiffTool takes ownership of the catalog managers |
114 |
|
✗ |
DiffForwarder diff_forwarder(mgr_from, mgr_to, diff_listener); |
115 |
|
✗ |
if (!diff_forwarder.Init()) |
116 |
|
✗ |
throw EPublish("cannot initialize difference engine"); |
117 |
|
✗ |
diff_forwarder.Run(PathString()); |
118 |
|
|
} |
119 |
|
|
|
120 |
|
|
} // namespace publish |
121 |
|
|
|