www.mooseframework.org
TheWarehouse.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include <map>
13 #include <string>
14 #include <vector>
15 #include <unordered_map>
16 #include <iostream>
17 #include <mutex>
18 
19 #include "MooseObject.h"
20 #include "MooseHashing.h"
21 
22 class MooseObject;
23 class Storage;
24 class TheWarehouse;
25 
31 class Attribute
32 {
33 public:
36  Attribute(TheWarehouse & w, const std::string name);
37  virtual ~Attribute() {}
38 
39  inline bool operator==(const Attribute & other) const
40  {
41  return _id == other._id && isEqual(other);
42  }
43  inline bool operator!=(const Attribute & other) const { return !(*this == other); }
44 
48  inline unsigned int id() const { return _id; }
49 
56  virtual size_t hash() const = 0;
57 
59  virtual void initFrom(const MooseObject * obj) = 0;
63  virtual bool isMatch(const Attribute & other) const = 0;
67  virtual bool isEqual(const Attribute & other) const = 0;
70  virtual std::unique_ptr<Attribute> clone() const = 0;
71 
72 private:
73  int _id = -1;
74 };
75 
78 bool operator==(const std::unique_ptr<Attribute> & lhs, const std::unique_ptr<Attribute> & rhs);
79 
80 namespace std
81 {
83 template <>
84 struct hash<Attribute>
85 {
86 public:
87  size_t operator()(const Attribute & attrib) const
88  {
89  size_t h = attrib.hash();
90  Moose::hash_combine(h, attrib.id());
91  return h;
92  }
93 };
94 
96 template <>
97 struct hash<std::vector<std::unique_ptr<Attribute>>>
98 {
99 public:
100  size_t operator()(const std::vector<std::unique_ptr<Attribute>> & attribs) const
101  {
102  size_t h = 0;
103  for (auto & attrib : attribs)
104  Moose::hash_combine(h, *attrib);
105  return h;
106  }
107 };
108 }
109 
120 {
121 public:
128  class Query
129  {
130  public:
133  Query(TheWarehouse & w) : _w(&w) { _attribs.reserve(5); }
134 
135  Query & operator=(const Query & other)
136  {
137  if (this == &other)
138  return *this;
139 
140  _w = other._w;
141  _attribs.clear();
142  _attribs.reserve(other._attribs.size());
143  for (auto & attrib : other._attribs)
144  _attribs.push_back(attrib->clone());
145  return *this;
146  }
147  Query(const Query & other) : _w(other._w)
148  {
149  _attribs.reserve(other._attribs.size());
150  for (auto & attrib : other._attribs)
151  _attribs.push_back(attrib->clone());
152  }
153 
156  template <typename T, typename... Args>
157  Query & condition(Args &&... args)
158  {
159  _attribs.emplace_back(new T(*_w, std::forward<Args>(args)...));
160  return *this;
161  }
162 
164  Query clone() const { return Query(*this); }
167  size_t count() { return _w->count(_attribs); }
168 
170  std::vector<std::unique_ptr<Attribute>> attributes() { return clone()._attribs; }
171 
174  template <typename T>
175  std::vector<T *> & queryInto(std::vector<T *> & results)
176  {
177  return _w->queryInto(_attribs, results);
178  }
179 
180  private:
181  TheWarehouse * _w = nullptr;
182  std::vector<std::unique_ptr<Attribute>> _attribs;
183  };
184 
185  TheWarehouse();
186  ~TheWarehouse();
187 
202  template <typename T, typename... Args>
203  unsigned int registerAttribute(const std::string & name, Args... dummy_args)
204  {
205  auto it = _attrib_ids.find(name);
206  if (it != _attrib_ids.end())
207  return it->second;
208 
209  _attrib_ids[name] = _attrib_list.size();
210  _attrib_list.push_back(std::unique_ptr<Attribute>(new T(*this, dummy_args...)));
211  return _attrib_list.size() - 1;
212  }
213 
217  inline unsigned int attribID(const std::string & name)
218  {
219  auto it = _attrib_ids.find(name);
220  if (it != _attrib_ids.end())
221  return it->second;
222  mooseError("no ID exists for unregistered attribute '", name, "'");
223  }
224 
227  void add(std::shared_ptr<MooseObject> obj, const std::string & system);
231  void update(MooseObject * obj);
236  void update(MooseObject * obj, const Attribute & extra);
239  Query query() { return Query(*this); }
243  size_t count(const std::vector<std::unique_ptr<Attribute>> & conds);
249  template <typename T>
250  std::vector<T *> & queryInto(const std::vector<std::unique_ptr<Attribute>> & conds,
251  std::vector<T *> & results)
252  {
253  return queryInto(queryID(conds), results);
254  }
255 
256 private:
257  size_t queryID(const std::vector<std::unique_ptr<Attribute>> & conds);
258 
259  template <typename T>
260  std::vector<T *> & queryInto(int query_id, std::vector<T *> & results, bool show_all = false)
261  {
262  std::lock_guard<std::mutex> lock(_obj_cache_mutex);
263  auto & objs = query(query_id);
264  results.clear();
265  results.reserve(objs.size());
266  for (unsigned int i = 0; i < objs.size(); i++)
267  {
268  auto obj = objs[i];
269  mooseAssert(dynamic_cast<T *>(obj), "queried object has incompatible c++ type");
270  if (show_all || obj->enabled())
271  results.push_back(dynamic_cast<T *>(obj));
272  }
273  return results;
274  }
275 
277  int prepare(std::vector<std::unique_ptr<Attribute>> conds);
278 
281  const std::vector<MooseObject *> & query(int query_id);
282 
283  void readAttribs(const MooseObject * obj,
284  const std::string & system,
285  std::vector<std::unique_ptr<Attribute>> & attribs);
286 
287  std::unique_ptr<Storage> _store;
288  std::vector<std::shared_ptr<MooseObject>> _objects;
289  std::unordered_map<MooseObject *, size_t> _obj_ids;
290 
291  // Results from queries are cached here. The outer vector index is the query id as stored by the
292  // _query_cache data structure. A list objects that match each query id are stored.
293  std::vector<std::vector<MooseObject *>> _obj_cache;
294  // This stores a query id for every query keyed by the query conditions/attributes.
295  // User-initiated queries check this map to see if a queries results have already been cached.
296  // The query id is an index into the _obj_cache data structure.
297  std::unordered_map<std::vector<std::unique_ptr<Attribute>>, int> _query_cache;
298 
299  std::unordered_map<std::string, unsigned int> _attrib_ids;
300  std::vector<std::unique_ptr<Attribute>> _attrib_list;
301 
302  std::mutex _obj_mutex;
303  std::mutex _query_cache_mutex;
304  std::mutex _obj_cache_mutex;
305 };
306 
unsigned int id() const
returns the unique attribute ID associated with all attributes that have the same (mose derived) clas...
Definition: TheWarehouse.h:48
std::mutex _obj_cache_mutex
Definition: TheWarehouse.h:304
Query & operator=(const Query &other)
Definition: TheWarehouse.h:135
bool operator!=(const Attribute &other) const
Definition: TheWarehouse.h:43
Attribute is an abstract class that can be implemented in order to track custom metadata about MooseO...
Definition: TheWarehouse.h:31
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
virtual bool isEqual(const Attribute &other) const =0
isEqual returns true if the meta-data stored in this attribute is identical to that stored in other...
bool operator==(const Attribute &other) const
Definition: TheWarehouse.h:39
Query(TheWarehouse &w)
Creates a new query operating on the given warehouse w.
Definition: TheWarehouse.h:133
Attribute(TheWarehouse &w, const std::string name)
Constructs/initializes a new attribute with the specified name for use in warehouse w...
Definition: TheWarehouse.C:36
void hash_combine(std::size_t &)
Used for hash function specialization for Attribute objects.
Definition: MooseHashing.h:21
Query & condition(Args &&... args)
Adds a new condition to the query.
Definition: TheWarehouse.h:157
std::unordered_map< std::string, unsigned int > _attrib_ids
Definition: TheWarehouse.h:299
size_t operator()(const Attribute &attrib) const
Definition: TheWarehouse.h:87
std::mutex _query_cache_mutex
Definition: TheWarehouse.h:303
size_t count()
count returns the number of results that match the query (this requires actually running the query)...
Definition: TheWarehouse.h:167
size_t queryID(const std::vector< std::unique_ptr< Attribute >> &conds)
Definition: TheWarehouse.C:198
nl system()
bool operator==(const std::unique_ptr< Attribute > &lhs, const std::unique_ptr< Attribute > &rhs)
TheWarehouse uses this operator function for indexing and caching queries.
Definition: TheWarehouse.C:31
std::vector< std::shared_ptr< MooseObject > > _objects
Definition: TheWarehouse.h:288
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:42
std::unique_ptr< Storage > _store
Definition: TheWarehouse.h:287
TheWarehouse is a container for MooseObjects that allows querying/filtering over various customizeabl...
Definition: TheWarehouse.h:119
std::vector< T * > & queryInto(int query_id, std::vector< T *> &results, bool show_all=false)
Definition: TheWarehouse.h:260
int prepare(std::vector< std::unique_ptr< Attribute >> conds)
prepares a query and returns an associated query_id (i.e. for use with the query function).
Definition: TheWarehouse.C:141
TheWarehouse * _w
Definition: TheWarehouse.h:181
std::unordered_map< std::vector< std::unique_ptr< Attribute > >, int > _query_cache
Definition: TheWarehouse.h:297
std::mutex _obj_mutex
Definition: TheWarehouse.h:302
virtual ~Attribute()
Definition: TheWarehouse.h:37
std::unordered_map< MooseObject *, size_t > _obj_ids
Definition: TheWarehouse.h:289
std::vector< std::unique_ptr< Attribute > > _attribs
Definition: TheWarehouse.h:182
void update(MooseObject *obj)
update updates the metadata/attribute-info stored for the given object obj that must already exists i...
Definition: TheWarehouse.C:129
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
Definition: TheWarehouse.h:239
Query clone() const
clone creates and returns an independent copy of the query in its current state.
Definition: TheWarehouse.h:164
unsigned int registerAttribute(const std::string &name, Args... dummy_args)
registers a new "tracked" attribute of type T for the warehouse.
Definition: TheWarehouse.h:203
void readAttribs(const MooseObject *obj, const std::string &system, std::vector< std::unique_ptr< Attribute >> &attribs)
Definition: TheWarehouse.C:228
void add(std::shared_ptr< MooseObject > obj, const std::string &system)
add adds a new object to the warehouse and stores attributes/metadata about it for running queries/fi...
Definition: TheWarehouse.C:94
std::vector< T * > & queryInto(const std::vector< std::unique_ptr< Attribute >> &conds, std::vector< T *> &results)
queryInto takes the given conditions (i.e.
Definition: TheWarehouse.h:250
std::vector< T * > & queryInto(std::vector< T *> &results)
queryInto executes the query and stores the results in the given vector.
Definition: TheWarehouse.h:175
std::vector< std::unique_ptr< Attribute > > attributes()
attribs returns a copy of the constructed Attribute list for the query in its current state...
Definition: TheWarehouse.h:170
unsigned int attribID(const std::string &name)
Returns a unique ID associated with the given attribute name - i.e.
Definition: TheWarehouse.h:217
Query is a convenient way to construct and pass around (possible partially constructed) warehouse que...
Definition: TheWarehouse.h:128
size_t count(const std::vector< std::unique_ptr< Attribute >> &conds)
count returns the number of objects that match the provided query conditions.
Definition: TheWarehouse.C:215
size_t operator()(const std::vector< std::unique_ptr< Attribute >> &attribs) const
Definition: TheWarehouse.h:100
virtual bool isMatch(const Attribute &other) const =0
isMatch returns true if the meta-data stored in this attribute is equivalent to that stored in other...
virtual void initFrom(const MooseObject *obj)=0
initFrom reads and stores the desired meta-data from obj for later matching comparisons.
Query(const Query &other)
Definition: TheWarehouse.h:147
virtual size_t hash() const =0
This function must return a deterministic value that is uniquely determined by the data the attribute...
std::vector< std::unique_ptr< Attribute > > _attrib_list
Definition: TheWarehouse.h:300
std::vector< std::vector< MooseObject * > > _obj_cache
Definition: TheWarehouse.h:293
virtual std::unique_ptr< Attribute > clone() const =0
clone creates and returns and identical (deep) copy of this attribute - i.e.