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-2019 OpenFOAM Foundation
9  Copyright (C) 2015-2024 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
83 (
84  const Time& t,
85  const label initialCapacity
86 )
87 :
89  (
90  IOobject
91  (
92  word::validate(t.caseName()),
93  t.path(),
94  t,
95  IOobjectOption::NO_READ,
96  IOobjectOption::AUTO_WRITE,
97  IOobjectOption::NO_REGISTER
98  ),
99  true // to flag that this is the top-level regIOobject
100  ),
101  HashTable<regIOobject*>(initialCapacity),
102  time_(t),
103  parent_(t),
104  dbDir_(name()),
105  event_(1),
106  cacheTemporaryObjectsActive_(false),
107  cacheTemporaryObjects_(0),
108  temporaryObjects_(0)
109 {}
110 
111 
112 Foam::objectRegistry::objectRegistry
113 (
114  const IOobject& io,
115  const label initialCapacity
116 )
117 :
118  regIOobject(io),
119  HashTable<regIOobject*>(initialCapacity),
120  time_(io.time()),
121  parent_(io.db()),
122  dbDir_(parent_.dbDir()/local()/name()),
123  event_(1),
124  cacheTemporaryObjectsActive_(false),
125  cacheTemporaryObjects_(0),
126  temporaryObjects_(0)
127 {
128  writeOpt(IOobjectOption::AUTO_WRITE);
129 }
130 
131 
132 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
133 
135 {
137 }
138 
139 
140 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
143 {
144  return (this == &static_cast<const objectRegistry&>(time_));
145 }
146 
147 
149 {
150  return classesImpl(*this, predicates::always());
151 }
152 
153 
155 (
156  const word& name,
157  IOobjectOption ioOpt
158 ) const
159 {
160  return IOobject
161  (
162  name,
163  time().timeName(), // instance
164  *this,
165  ioOpt
166  );
167 }
168 
169 
171 (
172  const word& name,
176 ) const
177 {
178  return IOobject
179  (
180  name,
181  time().timeName(), // instance
182  *this,
183  IOobjectOption(rOpt, wOpt, regOpt)
184  );
185 }
186 
187 
188 // FUTURE?
189 //
190 // Foam::IOobject Foam::objectRegistry::newIOobject_constant
191 // (
192 // const word& name,
193 // IOobjectOption::readOption rOpt,
194 // IOobjectOption::writeOption wOpt,
195 // IOobjectOption::registerOption regOpt
196 // ) const
197 // {
198 // return IOobject
199 // (
200 // name,
201 // time().constant(), // instance
202 // *this,
203 // IOobjectOption(rOpt, wOpt, regOpt)
204 // );
205 // }
206 
207 
208 Foam::label Foam::objectRegistry::count(const char* clsName) const
209 {
210  // No nullptr check - only called with string literals
211  return count(static_cast<word>(clsName));
212 }
213 
216 {
218 }
219 
222 {
224 }
225 
226 
227 Foam::wordList Foam::objectRegistry::names(const char* clsName) const
228 {
229  // No nullptr check - only called with string literals
230  return names(static_cast<word>(clsName));
231 }
232 
233 
234 Foam::wordList Foam::objectRegistry::sortedNames(const char* clsName) const
235 {
236  // No nullptr check - only called with string literals
237  return sortedNames(static_cast<word>(clsName));
238 }
239 
240 
242 (
243  const word& name,
244  const bool forceCreate,
245  const bool recursive
246 ) const
247 {
248  if (forceCreate && !foundObject<objectRegistry>(name, recursive))
249  {
250  objectRegistry* subObr = new objectRegistry
251  (
252  IOobject
253  (
254  name,
255  time().constant(),
256  *this,
260  )
261  );
262  subObr->store();
263  }
264 
265  return lookupObject<objectRegistry>(name, recursive);
266 }
267 
268 
269 Foam::label Foam::objectRegistry::getEvent() const
270 {
271  label curEvent = event_++;
272 
273  if (event_ == labelMax)
274  {
276  {
278  << "Event counter has overflowed. "
279  << "Resetting counter on all dependent objects." << nl
280  << "This might cause extra evaluations." << endl;
281  }
282 
283  // Reset event counter
284  curEvent = 1;
285  event_ = 2;
286 
287  // No need to reset dependent objects; overflow is now handled
288  // in regIOobject::upToDate
289  }
290 
291  return curEvent;
292 }
293 
294 
295 bool Foam::objectRegistry::checkIn(regIOobject* io) const
296 {
297  if (!io) return false;
298 
299  objectRegistry& obr = const_cast<objectRegistry&>(*this);
300 
302  {
303  Pout<< "objectRegistry::checkIn : "
304  << name() << " : checking in " << io->name()
305  << " of type " << io->type()
306  << endl;
307  }
308 
309  // Delete cached object if it has the same name as io, and in the
310  // cacheTemporaryObjects list
311  if (!cacheTemporaryObjects_.empty())
312  {
313  auto cacheIter = cacheTemporaryObjects_.find(io->name());
314 
315  if (cacheIter.good())
316  {
317  iterator iter = obr.find(io->name());
318 
319  if
320  (
321  iter.good()
322  && iter.val() != io
323  && iter.val()->ownedByRegistry()
324  )
325  {
327  {
328  Pout<< "objectRegistry::checkIn : "
329  << name() << " : deleting cached object "
330  << io->name() << endl;
331  }
332 
333  cacheIter.val().first() = false;
334  deleteCachedObject(iter.val());
335  }
336  }
337  }
338 
339 
340  bool ok = obr.insert(io->name(), io);
341 
342  if (!ok && objectRegistry::debug)
343  {
345  << name() << " : Attempt to checkIn object with name "
346  << io->name() << " which was already checked in"
347  << endl;
348  }
349 
350  return ok;
351 }
352 
353 
354 bool Foam::objectRegistry::checkOut(regIOobject* io) const
355 {
356  if (!io) return false;
357 
358  objectRegistry& obr = const_cast<objectRegistry&>(*this);
359 
360  iterator iter = obr.find(io->name());
361 
362  if (iter.good())
363  {
365  {
366  Pout<< "objectRegistry::checkOut : "
367  << name() << " : checking out " << io->name()
368  << " of type " << io->type()
369  << endl;
370  }
371 
372  if (iter.val() != io)
373  {
375  {
377  << name() << " : Attempt to checkOut copy of "
378  << iter.key()
379  << endl;
380  }
381 
382  return false;
383  }
384 
385  return obr.erase(iter);
386  }
387 
388 
390  {
391  Pout<< "objectRegistry::checkOut : "
392  << name() << " : could not find " << io->name() << " in registry"
393  << endl;
394  }
395 
396  return false;
397 }
398 
401 {
402  return checkIn(&io);
403 }
404 
407 {
408  return checkOut(&io);
409 }
410 
412 bool Foam::objectRegistry::checkOut(const word& key) const
413 {
414  return const_cast<objectRegistry&>(*this).erase(key);
415 }
416 
417 
419 {
420  // Free anything owned by the registry, but first unset both
421  // 'ownedByRegistry' and 'registered' flags to ensure that the
422  // regIOobject destructor will not affect the registry
423 
424  for (iterator iter = begin(); iter != end(); ++iter)
425  {
426  regIOobject* ptr = iter.val();
427 
428  if (ptr && ptr->ownedByRegistry())
429  {
431  {
432  Pout<< "objectRegistry::clear : " << ptr->name() << nl;
433  }
434 
435  ptr->release(true); // Relinquish ownership and registration
436  delete ptr; // Delete also clears fileHandler watches
437  }
438  }
439 
441 }
442 
443 
445 {
448 }
449 
450 
451 bool Foam::objectRegistry::erase(const iterator& iter)
452 {
453  // Remove from registry - see notes in objectRegistry::clear()
454 
455  if (iter.good())
456  {
457  regIOobject* ptr = const_cast<iterator&>(iter).val();
458 
459  const bool ok = HashTable<regIOobject*>::erase(iter);
460 
461  if (ptr && ptr->ownedByRegistry())
462  {
463  ptr->release(true); // Relinquish ownership and registration
464  delete ptr; // Delete also clears fileHandler watches
465  }
466 
467  return ok;
468  }
469 
470  return false;
471 }
472 
475 {
476  return erase(find(key));
477 }
478 
480 Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
481 {
482  return eraseImpl(*this, keys.begin(), keys.end());
483 }
484 
486 Foam::label Foam::objectRegistry::erase(const UList<word>& keys)
487 {
488  return eraseImpl(*this, keys.begin(), keys.end());
489 }
490 
491 
492 void Foam::objectRegistry::rename(const word& newName)
493 {
494  regIOobject::rename(newName);
495 
496  // Adjust dbDir_ as well
497  const auto i = dbDir_.rfind('/');
498 
499  if (i == string::npos)
500  {
501  dbDir_ = newName;
502  }
503  else
504  {
505  dbDir_.replace(i+1, string::npos, newName);
506  }
507 }
508 
509 
511 (
512  const word& name,
513  const bool recursive
514 ) const
515 {
516  const_iterator iter = cfind(name);
517 
518  if (iter.good())
519  {
520  return iter.val();
521  }
522  else if (recursive && this->parentNotTime())
523  {
524  return parent_.cfindIOobject(name, recursive);
525  }
526 
527  return nullptr;
528 }
529 
530 
532 (
533  const word& name,
534  const bool recursive
535 ) const
536 {
537  return cfindIOobject(name, recursive);
538 }
539 
540 
542 {
543  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
544  {
545  if (iter.val()->modified())
546  {
547  return true;
548  }
549  }
550 
551  return false;
552 }
553 
554 
556 {
557  for (iterator iter = begin(); iter != end(); ++iter)
558  {
560  {
561  Pout<< "objectRegistry::readModifiedObjects() : "
562  << name() << " : Considering reading object "
563  << iter.key() << endl;
564  }
565 
566  iter.val()->readIfModified();
567  }
568 }
569 
570 
572 {
573  readModifiedObjects();
574  return true;
575 }
576 
577 
579 (
580  IOstreamOption streamOpt,
581  const bool writeOnProc
582 ) const
583 {
584  bool ok = true;
585 
586  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
587  {
589  {
590  const regIOobject& obj = *iter.val();
591 
592  Pout<< "objectRegistry::write() : "
593  << name() << " : Considering writing object "
594  << iter.key() << " of type "
595  << obj.type() << " with writeOpt "
596  << static_cast<int>(obj.writeOpt())
597  << " to file " << obj.objectRelPath() << endl;
598  }
599 
600  if (iter.val()->writeOpt() != IOobjectOption::NO_WRITE)
601  {
602  ok = iter.val()->writeObject(streamOpt, writeOnProc) && ok;
603  }
604  }
605 
606  return ok;
607 }
608 
609 
610 // ************************************************************************* //
bool contains(const word &name, const bool recursive=false) const
Does the registry contain the regIOobject object (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
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:827
writeOption
Enumeration defining write preferences.
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:184
void readModifiedObjects()
Read the objects that have been modified.
srcOptions erase("case")
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
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:50
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:531
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
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.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write the objects using stream options.
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
word timeName
Definition: getTimeIndex.H:3
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.
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 expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
void clear()
Remove all entries from table.
Definition: HashTable.C:749
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:223
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:392
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:105
bool isTimeDb() const noexcept
True if the registry is Time.
const direction noexcept
Definition: Scalar.H:258
bool checkOut()
Remove object from registry, and remove all file watches.
Definition: regIOobject.C:221
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:201
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:484
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:190
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:496
registerOption
Enumeration for use with registerObject(). Values map to bool (false/true)
#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:163
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
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:68
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:524
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:148
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:436
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
IOobject newIOobject(const word &name, IOobjectOption ioOpt) const
Create an IOobject at the current time instance (timeName) with the specified options.
Registry of regIOobjects.
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:168
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
Request registration (bool: true)
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()
Remove all entries from table and the table itself.
Definition: HashTable.C:774
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.
readOption
Enumeration defining read preferences.