| 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 |
|
|
|