1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// The following program merges contents of several object catalogs
// stored in "geners" binary metafiles
#include <fstream>
#include <iostream>
#include <vector>
#include <memory>
#include "Alignment/Geners/interface/CatalogIO.hh"
#include "Alignment/Geners/interface/ContiguousCatalog.hh"
#include "Alignment/Geners/interface/uriUtils.hh"
#include "CmdLine.hh"
using namespace gs;
using namespace std;
static void print_usage(const char *progname) {
cout << "\nUsage: " << progname << " -o output_file input_file0 input_file1 ...\n\n"
<< "This program merges the contents of several object catalogs stored "
"in \"geners\"\n"
<< "binary metafiles. The output metafile can be used as a single "
"\"geners\" archive\n"
<< "which includes all items from the merged catalogs.\n"
<< endl;
}
static const char *update_uri(const char *inputfile, const std::string &originalUri) {
static std::string result, old_inputfile, old_URI;
if (old_inputfile != inputfile || old_URI != originalUri) {
old_inputfile = inputfile;
old_URI = originalUri;
result = joinDir1WithName2(inputfile, originalUri.c_str());
}
return result.c_str();
}
static ItemLocation update_location(const char *inputfile, const ItemLocation &original) {
ItemLocation loc(original);
loc.setURI(update_uri(inputfile, original.URI()));
return loc;
}
int main(int argc, char const *argv[]) {
CmdLine cmdline(argc, argv);
if (argc == 1) {
print_usage(cmdline.progname());
return 0;
}
std::string outputfile;
std::vector<std::string> inputfiles;
try {
cmdline.require("-o") >> outputfile;
cmdline.optend();
while (cmdline) {
std::string s;
cmdline >> s;
inputfiles.push_back(s);
}
if (inputfiles.empty())
throw CmdLineError("must specify at least one input file");
} catch (CmdLineError &e) {
cerr << "Error in " << cmdline.progname() << ": " << e.str() << endl;
print_usage(cmdline.progname());
return 1;
}
// Before we perform any significant data processing,
// make sure that we can open all input files
const unsigned nfiles = inputfiles.size();
for (unsigned ifile = 0; ifile < nfiles; ++ifile) {
const std::string &inputfile(inputfiles[ifile]);
ifstream in(inputfile.c_str(), ios_base::binary);
if (!in.is_open()) {
cerr << "Error: failed to open file \"" << inputfile << "\"" << endl;
return 1;
}
}
// Variables which summarize the combined catalog
unsigned totalMergeLevel = 0, lastCompressionCode = 0;
bool compressionCodeMixed = false;
std::vector<std::string> allAnnotations;
ContiguousCatalog merged;
// Now, do the real cycle over the input files
for (unsigned ifile = 0; ifile < nfiles; ++ifile) {
const std::string &inputfile(inputfiles[ifile]);
const unsigned long long fileOffset = merged.size();
ifstream in(inputfile.c_str(), ios_base::binary);
if (!in.is_open()) {
cerr << "Error: failed to open file \"" << inputfile << "\"" << endl;
return 1;
}
unsigned compressionCode = 0, mergeLevel = 0;
std::vector<std::string> annotations;
std::unique_ptr<ContiguousCatalog> cat;
try {
cat = std::unique_ptr<ContiguousCatalog>(
readBinaryCatalog<ContiguousCatalog>(in, &compressionCode, &mergeLevel, &annotations, true));
} catch (std::exception &e) {
cerr << "Failed to read catalog from file \"" << inputfile << "\". " << e.what() << endl;
return 1;
}
// Update compression code info
if (ifile)
if (compressionCode != lastCompressionCode)
compressionCodeMixed = true;
lastCompressionCode = compressionCode;
// Update merge level
if (mergeLevel == 0)
++mergeLevel;
totalMergeLevel += mergeLevel;
// Update annotations
std::copy(annotations.begin(), annotations.end(), std::back_inserter(allAnnotations));
const unsigned long long last = cat->largestId();
for (unsigned long long id = cat->smallestId(); id <= last; ++id) {
if (!cat->itemExists(id))
continue;
std::shared_ptr<const CatalogEntry> e = cat->retrieveEntry(id);
const unsigned long long newid = merged.makeEntry(*e,
e->compressionCode(),
e->itemLength(),
update_location(inputfile.c_str(), e->location()),
e->offset() + fileOffset);
assert(newid);
}
}
ofstream of(outputfile.c_str(), ios_base::binary);
if (!of.is_open()) {
cerr << "Error: failed to open file \"" << outputfile << "\"" << endl;
return 1;
}
const unsigned compress = compressionCodeMixed ? 1 : lastCompressionCode;
if (!writeBinaryCatalog(of, compress, totalMergeLevel, allAnnotations, merged)) {
cerr << "Error: failed to write merged catalog to file \"" << outputfile << "\"" << endl;
return 1;
}
of.close();
return 0;
}
|