LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ParameterSetRegistry.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_ParameterSetRegistry_h
2 #define fhiclcpp_ParameterSetRegistry_h
3 
4 // ======================================================================
5 //
6 // ParameterSetRegistry
7 //
8 // ======================================================================
9 
10 #include "fhiclcpp/ParameterSet.h"
12 #include "fhiclcpp/exception.h"
13 #include "fhiclcpp/fwd.h"
14 
15 #include <mutex>
16 #include <unordered_map>
17 
18 struct sqlite3;
19 struct sqlite3_stmt;
20 
21 namespace fhicl {
22 
23  class ParameterSetRegistry;
24 
25  namespace detail {
26  class HashParameterSetID;
27  void throwOnSQLiteFailure(int rc, char* msg = nullptr);
28  void throwOnSQLiteFailure(sqlite3* db, char* msg = nullptr);
29  }
30 }
31 
33 public:
34  size_t operator()(ParameterSetID const& id) const;
35 
36 private:
37  std::hash<std::string> hash_;
38 };
39 
41 public:
42  ParameterSetRegistry(ParameterSet const&) = delete;
44  ParameterSetRegistry& operator=(ParameterSet const&) = delete;
45  ParameterSetRegistry& operator=(ParameterSet&&) = delete;
47 
48  // Type aliases.
49  using collection_type = std::
50  unordered_map<ParameterSetID, ParameterSet, detail::HashParameterSetID>;
51  using key_type = collection_type::key_type;
52  using mapped_type = collection_type::mapped_type;
53  using value_type = collection_type::value_type;
54  using size_type = collection_type::size_type;
56 
57  // DB interaction.
58  static void importFrom(sqlite3* db);
59  static void exportTo(sqlite3* db);
60  static void stageIn();
61 
62  // Observers.
63  static bool empty();
64  static size_type size();
65 
66  // Put:
67  // 1. A single ParameterSet.
68  static ParameterSetID const& put(ParameterSet const& ps);
69  // 2. A range of iterator to ParameterSet.
70  template <class FwdIt>
71  static std::enable_if_t<
72  std::is_same_v<typename std::iterator_traits<FwdIt>::value_type,
73  mapped_type>>
74  put(FwdIt begin, FwdIt end);
75  // 3. A range of iterator to pair<ParameterSetID, ParameterSet>. For
76  // each pair, first == second.id() is a prerequisite.
77  template <class FwdIt>
78  static std::enable_if_t<
79  std::is_same_v<typename std::iterator_traits<FwdIt>::value_type,
80  value_type>>
81  put(FwdIt begin, FwdIt end);
82  // 4. A collection_type. For each value_type, first == second.id() is
83  // a prerequisite.
84  static void put(collection_type const& c);
85 
86  // Accessors.
87  static collection_type const& get() noexcept;
88  static ParameterSet const& get(ParameterSetID const& id);
89  static bool get(ParameterSetID const& id, ParameterSet& ps);
90  static bool has(ParameterSetID const& id);
91 
92 private:
94  static ParameterSetRegistry& instance_();
95  const_iterator find_(ParameterSetID const& id);
96 
97  sqlite3* primaryDB_;
98  sqlite3_stmt* stmt_{nullptr};
99  collection_type registry_{};
100  static std::recursive_mutex mutex_;
101 };
102 
103 inline bool
105 {
106  std::lock_guard sentry{mutex_};
107  return instance_().registry_.empty();
108 }
109 
110 inline auto
112 {
113  std::lock_guard sentry{mutex_};
114  return instance_().registry_.size();
115 }
116 
117 // 1.
118 inline auto
120  -> ParameterSetID const&
121 {
122  std::lock_guard sentry{mutex_};
123  return instance_().registry_.emplace(ps.id(), ps).first->first;
124 }
125 
126 // 2.
127 template <class FwdIt>
128 inline auto
129 fhicl::ParameterSetRegistry::put(FwdIt b, FwdIt const e) -> std::enable_if_t<
130  std::is_same_v<typename std::iterator_traits<FwdIt>::value_type, mapped_type>>
131 {
132  // No lock here -- it will be acquired by 3.
133  for (; b != e; ++b) {
134  (void)put(*b);
135  }
136 }
137 
138 // 3.
139 template <class FwdIt>
140 inline auto
141 fhicl::ParameterSetRegistry::put(FwdIt const b, FwdIt const e)
142  -> std::enable_if_t<
143  std::is_same_v<typename std::iterator_traits<FwdIt>::value_type,
144  value_type>>
145 {
146  std::lock_guard sentry{mutex_};
147  instance_().registry_.insert(b, e);
148 }
149 
150 // 4.
151 inline void
153 {
154  // No lock here -- it will be acquired by 3.
155  put(c.cbegin(), c.cend());
156 }
157 
158 inline auto
160 {
161  std::lock_guard sentry{mutex_};
162  return instance_().registry_;
163 }
164 
165 inline auto
167  -> ParameterSet const&
168 {
169  std::lock_guard sentry{mutex_};
170  auto it = instance_().find_(id);
171  if (it == instance_().registry_.cend()) {
172  throw exception(error::cant_find, "Can't find ParameterSet")
173  << "with ID " << id.to_string() << " in the registry.";
174  }
175  return it->second;
176 }
177 
178 inline bool
180 {
181  std::lock_guard sentry{mutex_};
182  bool result{false};
183  auto it = instance_().find_(id);
184  if (it != instance_().registry_.cend()) {
185  ps = it->second;
186  result = true;
187  }
188  return result;
189 }
190 
191 inline bool
193 {
194  std::lock_guard sentry{mutex_};
195  auto const& reg = instance_().registry_;
196  return reg.find(id) != reg.cend();
197 }
198 
199 inline auto
201 {
202  static ParameterSetRegistry s_registry;
203  return s_registry;
204 }
205 
206 inline size_t
208 {
209  return hash_(id.to_string());
210 }
211 
212 #endif /* fhiclcpp_ParameterSetRegistry_h */
213 
214 // Local Variables:
215 // mode: c++
216 // End:
static ParameterSetID const & put(ParameterSet const &ps)
static collection_type const & get() noexcept
intermediate_table::const_iterator const_iterator
std::string to_string(Protection p)
Definition: Protection.cc:4
collection_type::const_iterator const_iterator
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
collection_type::value_type value_type
parameter set interface
size_t operator()(ParameterSetID const &id) const
collection_type::key_type key_type
static bool has(ParameterSetID const &id)
static std::recursive_mutex mutex_
void throwOnSQLiteFailure(int rc, char *msg=nullptr)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
collection_type::size_type size_type
Float_t e
Definition: plot.C:35
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:109
collection_type::mapped_type mapped_type
static ParameterSetRegistry & instance_()
std::unordered_map< ParameterSetID, ParameterSet, detail::HashParameterSetID > collection_type