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
|
#include "FWCore/ParameterSet/interface/VParameterSetEntry.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/src/split.h"
#include "FWCore/Utilities/interface/Digest.h"
#include <cassert>
#include <ostream>
#include <sstream>
namespace edm {
VParameterSetEntry::VParameterSetEntry() : tracked_(false), theVPSet_(), theIDs_() {}
VParameterSetEntry::VParameterSetEntry(std::vector<ParameterSet> const& vpset, bool isTracked)
: tracked_(isTracked), theVPSet_(new std::vector<ParameterSet>(vpset)), theIDs_() {}
VParameterSetEntry::VParameterSetEntry(std::string_view rep)
: tracked_(rep[0] == '+'), theVPSet_(), theIDs_(new std::vector<ParameterSetID>) {
assert(rep[0] == '+' || rep[0] == '-');
std::vector<std::string_view> temp;
// need a substring that starts at the '{'
std::string_view bracketedRepr = rep.substr(2);
split(std::back_inserter(temp), bracketedRepr, '{', ',', '}');
theIDs_->reserve(temp.size());
for (auto const& id : temp) {
theIDs_->emplace_back(std::string(id));
}
}
void VParameterSetEntry::toString(std::string& result) const {
assert(theIDs_);
result += tracked_ ? "+q" : "-q";
result += '{';
std::string start;
std::string const between(",");
for (std::vector<ParameterSetID>::const_iterator i = theIDs_->begin(), e = theIDs_->end(); i != e; ++i) {
result += start;
i->toString(result);
start = between;
}
result += '}';
}
void VParameterSetEntry::toDigest(cms::Digest& digest) const {
assert(theIDs_);
digest.append(tracked_ ? "+q{" : "-q{", 3);
bool started = false;
for (std::vector<ParameterSetID>::const_iterator i = theIDs_->begin(), e = theIDs_->end(); i != e; ++i) {
if (started)
digest.append(",", 1);
i->toDigest(digest);
started = true;
}
digest.append("}", 1);
}
std::string VParameterSetEntry::toString() const {
std::string result;
toString(result);
return result;
}
std::vector<ParameterSet> const& VParameterSetEntry::vpset() const {
fillVPSet();
return *theVPSet_;
}
// NOTE: This function, and other non-const functions of this class
// that expose internals, may be used in a way that causes the cached
// "theVPSet_" and "theIDs_" to be inconsistent.
// THIS PROBLEM NEEDS TO BE ADDRESSED
std::vector<ParameterSet>& VParameterSetEntry::vpsetForUpdate() {
fillVPSet();
return *theVPSet_;
}
void VParameterSetEntry::fillVPSet() const {
if (nullptr == theVPSet_.load()) {
auto tmp = std::make_unique<std::vector<ParameterSet>>();
tmp->reserve(theIDs_->size());
for (auto const& theID : *theIDs_) {
tmp->push_back(getParameterSet(theID));
}
VParameterSet* expected = nullptr;
if (theVPSet_.compare_exchange_strong(expected, tmp.get())) {
// theVPSet_ was equal to nullptr and now is equal to tmp.get()
tmp.release();
}
}
}
// NOTE: This function, and other non-const functions of this class
// that expose internals, may be used in a way that causes the cached
// "theVPSet_" and "theIDs_" to be inconsistent.
// THIS PROBLEM NEEDS TO BE ADDRESSED
ParameterSet& VParameterSetEntry::psetInVector(int i) {
assert(theVPSet_);
return theVPSet_->at(i);
}
std::vector<ParameterSet>::size_type VParameterSetEntry::size() const {
return theIDs_ ? theIDs_->size() : (theVPSet_ ? vpset().size() : 0);
}
void VParameterSetEntry::registerPsetsAndUpdateIDs() {
fillVPSet();
theIDs_ = value_ptr<std::vector<ParameterSetID>>(new std::vector<ParameterSetID>);
theIDs_->resize(theVPSet_->size());
for (std::vector<ParameterSet>::iterator i = theVPSet_->begin(), e = theVPSet_->end(); i != e; ++i) {
if (!i->isRegistered()) {
i->registerIt();
}
theIDs_->at(i - theVPSet_->begin()) = i->id();
}
}
std::string VParameterSetEntry::dump(unsigned int indent) const {
std::string indentation(indent, ' ');
std::ostringstream os;
std::vector<ParameterSet> const& vps = vpset();
os << "VPSet " << (isTracked() ? "tracked" : "untracked") << " = ({" << std::endl;
std::string start;
std::string const between(",\n");
for (std::vector<ParameterSet>::const_iterator i = vps.begin(), e = vps.end(); i != e; ++i) {
os << start << indentation << i->dump(indent);
start = between;
}
if (!vps.empty()) {
os << std::endl;
}
os << indentation << "})";
return os.str();
}
std::ostream& operator<<(std::ostream& os, VParameterSetEntry const& vpsetEntry) {
os << vpsetEntry.dump();
return os;
}
} // namespace edm
|