LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProcessHistory.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
7 #include "cetlib/MD5Digest.h"
8 #include "cetlib/container_algorithms.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_(std::move(rhs.data_)), transients_{std::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_ = std::move(rhs.data_);
67  transients_ = std::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 
123  {
124  return data_[i];
125  }
126 
129  {
130  return data_[i];
131  }
132 
135  {
136  return data_.at(i);
137  }
138 
141  {
142  return data_.at(i);
143  }
144 
147  {
148  return data_.begin();
149  }
150 
153  {
154  return data_.end();
155  }
156 
159  {
160  return data_.cbegin();
161  }
162 
165  {
166  return data_.cend();
167  }
168 
171  {
172  return data_.rbegin();
173  }
174 
177  {
178  return data_.rend();
179  }
180 
183  {
184  return data_.crbegin();
185  }
186 
189  {
190  return data_.crend();
191  }
192 
195  {
196  return data_;
197  }
198 
199  ProcessHistoryID const&
201  {
202  // Note: threading: We may be called by Principal::addProcessEntry()
203  // Note: threading: with the mutex already locked, so we use
204  // a recursive mutex.
205  std::lock_guard sentry{mutex_};
206  if (transients_.get().phid_.isValid()) {
207  return transients_.get().phid_;
208  }
209  // This implementation is ripe for optimization.
210  // We do not use operator<< because it does not write out everything.
211  ostringstream oss;
212  for (auto I = data_.begin(), E = data_.end(); I != E; ++I) {
213  oss << I->processName() << ' ' << I->parameterSetID() << ' '
214  << I->releaseVersion() << ' '
215  << ' '; // retain extra spaces for backwards compatibility
216  }
217  string stringrep = oss.str();
218  cet::MD5Digest md5alg(stringrep);
219  ProcessHistoryID tmp(md5alg.digest().toString());
220  transients_.get().phid_.swap(tmp);
221  return transients_.get().phid_;
222  }
223 
224  std::optional<ProcessConfiguration>
226  {
227  std::lock_guard sentry{mutex_};
228  for (const_iterator i = data_.begin(), e = data_.end(); i != e; ++i) {
229  if (i->processName() == name) {
230  return std::make_optional(*i);
231  }
232  }
233  return std::nullopt;
234  }
235 
236  void
238  {
239  a.swap(b);
240  }
241 
242  bool
244  {
245  return a.data() == b.data();
246  }
247 
248  bool
250  {
251  return !(a == b);
252  }
253 
254  bool
256  {
257  if (a.size() >= b.size()) {
258  return false;
259  }
260  for (auto itA = a.data().cbegin(),
261  itB = b.data().cbegin(),
262  itAEnd = a.data().cend();
263  itA != itAEnd;
264  ++itA, ++itB) {
265  if (*itA != *itB) {
266  return false;
267  }
268  }
269  return true;
270  }
271 
272  bool
274  {
275  return isAncestor(b, a);
276  }
277 
278  ostream&
279  operator<<(ostream& ost, ProcessHistory const& ph)
280  {
281  ost << "Process History = ";
282  copy_all(ph, ostream_iterator<ProcessHistory::value_type>(ost, ";"));
283  return ost;
284  }
285 
286 } // namespace art
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_
bool empty() const
Transient< Transients > transients_
const_iterator begin() const
STL namespace.
std::recursive_mutex & get_mutex() const
size_type capacity() const
Float_t tmp
Definition: plot.C:35
bool operator!=(ScheduleID const left, ScheduleID const right) noexcept
Definition: ScheduleID.cc:41
const_reverse_iterator rend() const
reference operator[](size_type i)
std::ostream & operator<<(std::ostream &os, const GroupSelector &gs)
const_reverse_iterator crend() const
Float_t E
Definition: plot.C:20
const_iterator cbegin() const
collection_type::const_iterator const_iterator
const_reverse_iterator crbegin() const
const_iterator cend() const
collection_type::reference reference
bool isAncestor(ProcessHistory const &a, ProcessHistory const &b)
collection_type data_
std::optional< ProcessConfiguration > getConfigurationForProcess(std::string const &name) const
const_reverse_iterator rbegin() const
collection_type::size_type size_type
size_type size() const
void reserve(size_type n)
Definition: MVAAlg.h:12
void swap(ProcessHistory &other)
Char_t n[5]
ProcessHistory & operator=(ProcessHistory const &)
Float_t e
Definition: plot.C:35
std::vector< value_type > collection_type
void push_back(const_reference t)
collection_type::const_reverse_iterator const_reverse_iterator
collection_type const & data() const
ProcessHistoryID const & id() const
Hash< ProcessHistoryType > ProcessHistoryID
bool isDescendant(ProcessHistory const &a, ProcessHistory const &b)
collection_type::const_reference const_reference