objectRegistry.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "objectRegistry.H"
30 #include "Time.H"
31 #include "predicates.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(objectRegistry, 0);
38 }
39 
40 
41 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 // Templated implementation for erase() with iterator range.
47 // Prefer not to expose directly.
48 template<class InputIter>
49 static label eraseImpl(objectRegistry& obr, InputIter first, InputIter last)
50 {
51  label changed = 0;
52 
53  for
54  (
55  const label nTotal = obr.size();
56  changed < nTotal && first != last; // Terminate early
57  ++first
58  )
59  {
60  if (obr.erase(*first))
61  {
62  ++changed;
63  }
64  }
65 
66  return changed;
67 }
68 
69 } // End namespace Foam
70 
71 
72 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
73 
74 bool Foam::objectRegistry::parentNotTime() const noexcept
75 {
76  return (&parent_ != static_cast<const objectRegistry*>(&time_));
77 }
78 
79 
80 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81 
82 Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
83 :
85  (
86  IOobject
87  (
88  word::validate(t.caseName()),
89  t.path(),
90  t,
91  IOobject::NO_READ,
92  IOobject::AUTO_WRITE,
93  false
94  ),
95  true // to flag that this is the top-level regIOobject
96  ),
97  HashTable<regIOobject*>(nObjects),
98  time_(t),
99  parent_(t),
100  dbDir_(name()),
101  event_(1)
102 {}
103 
104 
105 Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects)
106 :
107  regIOobject(io),
108  HashTable<regIOobject*>(nObjects),
109  time_(io.time()),
110  parent_(io.db()),
111  dbDir_(parent_.dbDir()/local()/name()),
112  event_(1)
113 {
114  writeOpt(IOobject::AUTO_WRITE);
115 }
116 
117 
118 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
119 
121 {
123 }
124 
125 
126 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
129 {
130  return (this == &static_cast<const objectRegistry&>(time_));
131 }
132 
135 {
136  return classesImpl(*this, predicates::always());
137 }
138 
139 
140 Foam::label Foam::objectRegistry::count(const char* clsName) const
141 {
142  // No nullptr check - only called with string literals
143  return count(static_cast<word>(clsName));
144 }
145 
146 
149 {
150  return objectsTypeImpl<const regIOobject>(*this, predicates::always());
151 }
152 
153 
156 {
157  return objectsTypeImpl<const regIOobject>(*this, predicates::always());
158 }
159 
160 
163 {
164  return objectsTypeImpl<regIOobject>(*this, predicates::always());
165 }
166 
169 {
171 }
172 
175 {
177 }
178 
179 
180 Foam::wordList Foam::objectRegistry::names(const char* clsName) const
181 {
182  // No nullptr check - only called with string literals
183  return names(static_cast<word>(clsName));
184 }
185 
186 
187 Foam::wordList Foam::objectRegistry::sortedNames(const char* clsName) const
188 {
189  // No nullptr check - only called with string literals
190  return sortedNames(static_cast<word>(clsName));
191 }
192 
193 
195 (
196  const word& name,
197  const bool forceCreate,
198  const bool recursive
199 ) const
200 {
201  if (forceCreate && !foundObject<objectRegistry>(name, recursive))
202  {
203  objectRegistry* subObr = new objectRegistry
204  (
205  IOobject
206  (
207  name,
208  time().constant(),
209  *this,
212  )
213  );
214  subObr->store();
215  }
216 
217  return lookupObject<objectRegistry>(name, recursive);
218 }
219 
220 
221 Foam::label Foam::objectRegistry::getEvent() const
222 {
223  label curEvent = event_++;
224 
225  if (event_ == labelMax)
226  {
228  {
230  << "Event counter has overflowed. "
231  << "Resetting counter on all dependent objects." << nl
232  << "This might cause extra evaluations." << endl;
233  }
234 
235  // Reset event counter
236  curEvent = 1;
237  event_ = 2;
238 
239  // No need to reset dependent objects; overflow is now handled
240  // in regIOobject::upToDate
241  }
242 
243  return curEvent;
244 }
245 
246 
247 bool Foam::objectRegistry::checkIn(regIOobject* io) const
248 {
249  if (!io) return false;
250 
252  {
253  Pout<< "objectRegistry::checkIn : "
254  << name() << " : checking in " << io->name()
255  << " of type " << io->type()
256  << endl;
257  }
258 
259  objectRegistry& obr = const_cast<objectRegistry&>(*this);
260 
261  bool ok = obr.insert(io->name(), io);
262 
263  if (!ok && objectRegistry::debug)
264  {
266  << name() << " : Attempt to checkIn object with name "
267  << io->name() << " which was already checked in"
268  << endl;
269  }
270 
271  return ok;
272 }
273 
274 
275 bool Foam::objectRegistry::checkOut(regIOobject* io) const
276 {
277  if (!io) return false;
278 
279  objectRegistry& obr = const_cast<objectRegistry&>(*this);
280 
281  iterator iter = obr.find(io->name());
282 
283  if (iter.found())
284  {
286  {
287  Pout<< "objectRegistry::checkOut : "
288  << name() << " : checking out " << io->name()
289  << " of type " << io->type()
290  << endl;
291  }
292 
293  if (iter.val() != io)
294  {
296  {
298  << name() << " : Attempt to checkOut copy of "
299  << iter.key()
300  << endl;
301  }
302 
303  return false;
304  }
305 
306  return obr.erase(iter);
307  }
308 
309 
311  {
312  Pout<< "objectRegistry::checkOut : "
313  << name() << " : could not find " << io->name() << " in registry"
314  << endl;
315  }
316 
317  return false;
318 }
319 
322 {
323  return checkIn(&io);
324 }
325 
328 {
329  return checkOut(&io);
330 }
331 
333 bool Foam::objectRegistry::checkOut(const word& key) const
334 {
335  return const_cast<objectRegistry&>(*this).erase(key);
336 }
337 
338 
340 {
341  // Free anything owned by the registry, but first unset both
342  // 'ownedByRegistry' and 'registered' flags to ensure that the
343  // regIOobject destructor will not affect the registry
344 
345  for (iterator iter = begin(); iter != end(); ++iter)
346  {
347  regIOobject* ptr = iter.val();
348 
349  if (ptr && ptr->ownedByRegistry())
350  {
352  {
353  Pout<< "objectRegistry::clear : " << ptr->name() << nl;
354  }
355 
356  ptr->release(true); // Relinquish ownership and registration
357  delete ptr; // Delete also clears fileHandler watches
358  }
359  }
360 
362 }
363 
364 
366 {
369 }
370 
371 
372 bool Foam::objectRegistry::erase(const iterator& iter)
373 {
374  // Remove from registry - see notes in objectRegistry::clear()
375 
376  if (iter.found())
377  {
378  regIOobject* ptr = const_cast<iterator&>(iter).val();
379 
380  const bool ok = HashTable<regIOobject*>::erase(iter);
381 
382  if (ptr && ptr->ownedByRegistry())
383  {
384  ptr->release(true); // Relinquish ownership and registration
385  delete ptr; // Delete also clears fileHandler watches
386  }
387 
388  return ok;
389  }
390 
391  return false;
392 }
393 
396 {
397  return erase(find(key));
398 }
399 
401 Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
402 {
403  return eraseImpl(*this, keys.begin(), keys.end());
404 }
405 
407 Foam::label Foam::objectRegistry::erase(const UList<word>& keys)
408 {
409  return eraseImpl(*this, keys.begin(), keys.end());
410 }
411 
412 
413 void Foam::objectRegistry::rename(const word& newName)
414 {
415  regIOobject::rename(newName);
416 
417  // Adjust dbDir_ as well
418  const auto i = dbDir_.rfind('/');
419 
420  if (i == string::npos)
421  {
422  dbDir_ = newName;
423  }
424  else
425  {
426  dbDir_.replace(i+1, string::npos, newName);
427  }
428 }
429 
430 
432 (
433  const word& name,
434  const bool recursive
435 ) const
436 {
437  const_iterator iter = cfind(name);
438 
439  if (iter.found())
440  {
441  return iter.val();
442  }
443  else if (recursive && this->parentNotTime())
444  {
445  return parent_.cfindIOobject(name, recursive);
446  }
447 
448  return nullptr;
449 }
450 
451 
453 (
454  const word& name,
455  const bool recursive
456 ) const
457 {
458  return cfindIOobject(name, recursive);
459 }
460 
461 
463 {
464  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
465  {
466  if (iter.val()->modified())
467  {
468  return true;
469  }
470  }
471 
472  return false;
473 }
474 
475 
477 {
478  for (iterator iter = begin(); iter != end(); ++iter)
479  {
481  {
482  Pout<< "objectRegistry::readModifiedObjects() : "
483  << name() << " : Considering reading object "
484  << iter.key() << endl;
485  }
486 
487  iter.val()->readIfModified();
488  }
489 }
490 
491 
493 {
494  readModifiedObjects();
495  return true;
496 }
497 
498 
500 (
501  IOstreamOption streamOpt,
502  const bool valid
503 ) const
504 {
505  bool ok = true;
506 
507  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
508  {
510  {
511  const regIOobject& obj = *iter.val();
512 
513  Pout<< "objectRegistry::write() : "
514  << name() << " : Considering writing object "
515  << iter.key() << " of type "
516  << obj.type() << " with writeOpt "
517  << static_cast<int>(obj.writeOpt())
518  << " to file " << obj.objectRelPath() << endl;
519  }
520 
521  if (iter.val()->writeOpt() != IOobjectOption::NO_WRITE)
522  {
523  ok = iter.val()->writeObject(streamOpt, valid) && ok;
524  }
525  }
526 
527  return ok;
528 }
529 
530 
531 // ************************************************************************* //
bool found(const word &name, const bool recursive=false) const
Can the regIOobject object be found (by name).
string & replace(const std::string &s1, const std::string &s2, size_type pos=0)
Replace first occurrence of sub-string s1 with s2, beginning at pos.
Definition: string.C:101
UPtrList< const regIOobject > csorted() const
Return sorted list of objects.
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:790
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
void release(const bool unregister=false) noexcept
Set object as not ownedByRegistry.
Definition: regIOobjectI.H:174
void readModifiedObjects()
Read the objects that have been modified.
srcOptions erase("case")
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write the objects using stream options.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
bool erase(const iterator &iter)
Erase an entry specified by the given iterator.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
wordList names() const
The unsorted names of all objects.
virtual bool modified() const
Return true if any of the object&#39;s files have been modified.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:45
A simple container for options an IOstream can normally have.
Ignore writing from objectRegistry::writeObject()
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
StringType validate(const std::string &str, const UnaryPredicate &accept, const bool invert=false)
Return a copy of the input string with validated characters.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
Unary and binary predicates that always return true, useful for templating.
Definition: predicates.H:53
writeOption writeOpt() const noexcept
Get the write option.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
label count(const char *clsName) const
The number of objects of the given class name.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
A class for handling words, derived from Foam::string.
Definition: word.H:63
void clear()
Clear all entries from table.
Definition: HashTable.C:671
wordList sortedNames() const
The sorted names of all objects.
virtual ~objectRegistry()
Destructor, with checkOut() for all objects that are ownedByRegistry.
label getEvent() const
Return new event number.
bool local
Definition: EEqn.H:20
virtual bool readIfModified()
Read object if modified.
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:215
A HashTable similar to std::unordered_map.
Definition: HashTable.H:102
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:100
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:322
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
bool isTimeDb() const noexcept
True if the registry is Time.
const direction noexcept
Definition: Scalar.H:258
bool checkOut()
Remove all file watches and remove object from registry.
Definition: regIOobject.C:220
int debug
Static debugging option.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:193
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:413
void clearStorage()
Clear all entries from the registry and the table itself.
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
Definition: stdFoam.H:182
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:433
#define WarningInFunction
Report a warning using Foam::Warning.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
bool ownedByRegistry() const noexcept
Is this object owned by the registry?
Definition: regIOobjectI.H:30
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:130
Nothing to be read.
Automatically write from objectRegistry::writeObject()
void clear()
Clear all entries from the registry.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:69
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:499
constexpr label labelMax
Definition: label.H:55
static label eraseImpl(objectRegistry &obr, InputIter first, InputIter last)
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:115
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:343
Registry of regIOobjects.
UPtrList< const regIOobject > sorted() const
Return sorted list of objects.
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:160
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:166
bool checkIn()
Add object to registry, if not already registered.
Definition: regIOobject.C:184
const regIOobject * cfindIOobject(const word &name, const bool recursive=false) const
Return const pointer to the regIOobject.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
virtual void rename(const word &newName)
Rename.
Namespace for OpenFOAM.
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:690
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.