ProcessHistory.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
7 #include "cetlib/MD5Digest.h"
10 
11 #include <iterator>
12 #include <ostream>
13 #include <utility>
14 
15 using namespace cet;
16 using namespace std;
17 
18 namespace art {
19 
20  ProcessHistory::~ProcessHistory() = default;
21  ProcessHistory::ProcessHistory() = default;
22 
23  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
24  ProcessHistory::ProcessHistory(size_type const n) : data_(n) {}
25 
26  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
28 
29  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
30  // Note: We do not give the strong exception safety guarantee because
31  // data_ may be modified before the transients_ ctor throws.
32  // Note: We do give the basic exception safety guarantee.
34  : data_(rhs.data_), transients_{rhs.transients_}
35  {}
36 
37  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
38  // Note: We do not give the strong exception safety guarantee because
39  // data_ may be modified before the transients_ ctor throws.
40  // Note: We do give the basic exception safety guarantee.
42  : data_(move(rhs.data_)), transients_{move(rhs.transients_)}
43  {}
44 
45  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
46  // Note: We do not give the strong exception safety guarantee because
47  // data_ may be modified before the transients_ ctor throws.
48  // Note: We do give the basic exception safety guarantee.
51  {
52  if (this != &rhs) {
53  data_ = rhs.data_;
55  }
56  return *this;
57  }
58 
59  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
60  // Note: We do not give the strong exception safety guarantee because
61  // data_ may be modified before the transients_ ctor throws.
62  // Note: We do give the basic exception safety guarantee.
65  {
66  data_ = move(rhs.data_);
67  transients_ = move(rhs.transients_);
68  return *this;
69  }
70 
71  std::recursive_mutex&
73  {
74  return mutex_;
75  }
76 
77  // Note: Cannot be noexcept because the ProcessHistoryID ctor can throw!
78  // Note: We do not give the strong exception safety guarantee because
79  // data_ may be modified before the transients_ ctor throws.
80  // Note: We do give the basic exception safety guarantee.
81  void
83  {
84  data_.swap(other.data_);
85  transients_.get().phid_.swap(other.transients_.get().phid_);
86  }
87 
88  // Put the given ProcessConfiguration into the history.
89  // Note: Invalidates our ProcessHistoryID!
90  void
92  {
93  data_.push_back(t);
94  transients_.get().phid_ = ProcessHistoryID();
95  }
96 
97  bool
99  {
100  return data_.empty();
101  }
102 
105  {
106  return data_.size();
107  }
108 
111  {
112  return data_.capacity();
113  }
114 
115  void
117  {
118  data_.reserve(n);
119  }
120 
122  {
123  return data_[i];
124  }
125 
127  {
128  return data_[i];
129  }
130 
133  {
134  return data_.at(i);
135  }
136 
139  {
140  return data_.at(i);
141  }
142 
145  {
146  return data_.begin();
147  }
148 
151  {
152  return data_.end();
153  }
154 
157  {
158  return data_.cbegin();
159  }
160 
163  {
164  return data_.cend();
165  }
166 
169  {
170  return data_.rbegin();
171  }
172 
175  {
176  return data_.rend();
177  }
178 
181  {
182  return data_.crbegin();
183  }
184 
187  {
188  return data_.crend();
189  }
190 
193  {
194  return data_;
195  }
196 
199  {
200  // Note: threading: We may be called by Principal::addProcessEntry()
201  // Note: threading: with the mutex already locked, so we use
202  // a recursive mutex.
203  std::lock_guard sentry{mutex_};
204  if (transients_.get().phid_.isValid()) {
205  return transients_.get().phid_;
206  }
207  // This implementation is ripe for optimization.
208  // We do not use operator<< because it does not write out everything.
209  ostringstream oss;
210  for (auto I = data_.begin(), E = data_.end(); I != E; ++I) {
211  oss << I->processName() << ' ' << I->parameterSetID() << ' '
212  << I->releaseVersion() << ' '
213  << ' '; // retain extra spaces for backwards compatibility
214  }
215  string stringrep = oss.str();
216  cet::MD5Digest md5alg(stringrep);
217  ProcessHistoryID tmp(md5alg.digest().toString());
218  transients_.get().phid_.swap(tmp);
219  return transients_.get().phid_;
220  }
221 
222  std::optional<ProcessConfiguration>
224  {
225  std::lock_guard sentry{mutex_};
226  for (const_iterator i = data_.begin(), e = data_.end(); i != e; ++i) {
227  if (i->processName() == name) {
228  return std::make_optional(*i);
229  }
230  }
231  return std::nullopt;
232  }
233 
234  void
236  {
237  a.swap(b);
238  }
239 
240  bool
242  {
243  return a.data() == b.data();
244  }
245 
246  bool
248  {
249  return !(a == b);
250  }
251 
252  bool
254  {
255  if (a.size() >= b.size()) {
256  return false;
257  }
259  for (const_iterator itA = a.data().begin(),
260  itB = b.data().begin(),
261  itAEnd = a.data().end();
262  itA != itAEnd;
263  ++itA, ++itB) {
264  if (*itA != *itB) {
265  return false;
266  }
267  }
268  return true;
269  }
270 
271  bool
273  {
274  return isAncestor(b, a);
275  }
276 
277  ostream&
278  operator<<(ostream& ost, ProcessHistory const& ph)
279  {
280  ost << "Process History = ";
281  copy_all(ph, ostream_iterator<ProcessHistory::value_type>(ost, ";"));
282  return ost;
283  }
284 
285 } // namespace art
static QCString name
Definition: declinfo.cpp:673
reference at(size_type i)
bool operator==(Provenance const &a, Provenance const &b) noexcept
Definition: Provenance.cc:141
const_iterator end() const
std::recursive_mutex mutex_
collection_type::const_reference const_reference
MD5Result digest() const
Definition: MD5Digest.cc:137
std::string toString() const
Definition: MD5Digest.cc:45
bool empty() const
Transient< Transients > transients_
const_iterator begin() const
collection_type::reference reference
STL namespace.
std::recursive_mutex & get_mutex() const
size_type capacity() const
intermediate_table::const_iterator const_iterator
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &)
collection_type::const_iterator const_iterator
const_reverse_iterator rend() const
reference operator[](size_type i)
ProcessHistoryID id() const
Hash< ProcessHistoryType > ProcessHistoryID
collection_type::const_reverse_iterator const_reverse_iterator
std::ostream & operator<<(std::ostream &os, const GroupSelector &gs)
const_reverse_iterator crend() const
const double e
std::void_t< T > n
const double a
def move(depos, offset)
Definition: depos.py:107
const_iterator cbegin() const
const_reverse_iterator crbegin() const
const_iterator cend() const
string tmp
Definition: languages.py:63
bool isAncestor(ProcessHistory const &a, ProcessHistory const &b)
collection_type data_
std::optional< ProcessConfiguration > getConfigurationForProcess(std::string const &name) const
auto copy_all(FwdCont &, FwdIter)
std::vector< value_type > collection_type
const_reverse_iterator rbegin() const
size_type size() const
E
Definition: 018_def.c:13
static bool * b
Definition: config.cpp:1043
void reserve(size_type n)
void swap(ProcessHistory &other)
ProcessHistory & operator=(ProcessHistory const &)
void push_back(const_reference t)
collection_type const & data() const
collection_type::size_type size_type
bool isDescendant(ProcessHistory const &a, ProcessHistory const &b)