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-2020 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
75 {
76  return (&parent_ != dynamic_cast<const objectRegistry*>(&time_));
77 }
78 
79 
80 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
81 
82 const Foam::regIOobject* Foam::objectRegistry::cfindIOobject
83 (
84  const word& name,
85  const bool recursive
86 ) const
87 {
88  const_iterator iter = cfind(name);
89 
90  if (iter.found())
91  {
92  return iter.val();
93  }
94  else if (recursive && this->parentNotTime())
95  {
96  return parent_.cfindIOobject(name, recursive);
97  }
98 
99  return nullptr;
100 }
101 
102 
103 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
104 
105 Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
106 :
108  (
109  IOobject
110  (
111  word::validate(t.caseName()),
112  t.path(),
113  t,
114  IOobject::NO_READ,
115  IOobject::AUTO_WRITE,
116  false
117  ),
118  true // to flag that this is the top-level regIOobject
119  ),
120  HashTable<regIOobject*>(nObjects),
121  time_(t),
122  parent_(t),
123  dbDir_(name()),
124  event_(1)
125 {}
126 
127 
128 Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects)
129 :
130  regIOobject(io),
131  HashTable<regIOobject*>(nObjects),
132  time_(io.time()),
133  parent_(io.db()),
134  dbDir_(parent_.dbDir()/local()/name()),
135  event_(1)
136 {
138 }
139 
140 
141 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
142 
144 {
146 }
147 
148 
149 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
150 
152 {
153  return classesImpl(*this, predicates::always());
154 }
155 
156 
157 Foam::label Foam::objectRegistry::count(const char* clsName) const
158 {
159  // No nullptr check - only called with string literals
160  return count(static_cast<word>(clsName));
161 }
162 
163 
165 {
167 }
168 
169 
171 {
173 }
174 
175 
176 Foam::wordList Foam::objectRegistry::names(const char* clsName) const
177 {
178  // No nullptr check - only called with string literals
179  return names(static_cast<word>(clsName));
180 }
181 
182 
184 {
185  // No nullptr check - only called with string literals
186  return sortedNames(static_cast<word>(clsName));
187 }
188 
189 
191 (
192  const word& name,
193  const bool forceCreate,
194  const bool recursive
195 ) const
196 {
197  if (forceCreate && !foundObject<objectRegistry>(name, recursive))
198  {
199  objectRegistry* subObr = new objectRegistry
200  (
201  IOobject
202  (
203  name,
204  time().constant(),
205  *this,
208  )
209  );
210  subObr->store();
211  }
212 
213  return lookupObject<objectRegistry>(name, recursive);
214 }
215 
216 
218 {
219  label curEvent = event_++;
220 
221  if (event_ == labelMax)
222  {
224  {
226  << "Event counter has overflowed. "
227  << "Resetting counter on all dependent objects." << nl
228  << "This might cause extra evaluations." << endl;
229  }
230 
231  // Reset event counter
232  curEvent = 1;
233  event_ = 2;
234 
235  // No need to reset dependent objects; overflow is now handled
236  // in regIOobject::upToDate
237  }
238 
239  return curEvent;
240 }
241 
242 
244 {
245  if (!io) return false;
246 
248  {
249  Pout<< "objectRegistry::checkIn : "
250  << name() << " : checking in " << io->name()
251  << " of type " << io->type()
252  << endl;
253  }
254 
255  objectRegistry& obr = const_cast<objectRegistry&>(*this);
256 
257  bool ok = obr.insert(io->name(), io);
258 
259  if (!ok && objectRegistry::debug)
260  {
262  << name() << " : Attempt to checkIn object with name "
263  << io->name() << " which was already checked in"
264  << endl;
265  }
266 
267  return ok;
268 }
269 
270 
272 {
273  if (!io) return false;
274 
275  objectRegistry& obr = const_cast<objectRegistry&>(*this);
276 
277  iterator iter = obr.find(io->name());
278 
279  if (iter.found())
280  {
282  {
283  Pout<< "objectRegistry::checkOut : "
284  << name() << " : checking out " << io->name()
285  << " of type " << io->type()
286  << endl;
287  }
288 
289  if (iter.val() != io)
290  {
292  {
294  << name() << " : Attempt to checkOut copy of "
295  << iter.key()
296  << endl;
297  }
298 
299  return false;
300  }
301 
302  return obr.erase(iter);
303  }
304 
305 
307  {
308  Pout<< "objectRegistry::checkOut : "
309  << name() << " : could not find " << io->name() << " in registry"
310  << endl;
311  }
312 
313  return false;
314 }
315 
316 
318 {
319  return checkIn(&io);
320 }
321 
322 
324 {
325  return checkOut(&io);
326 }
327 
328 
329 bool Foam::objectRegistry::checkOut(const word& key) const
330 {
331  return const_cast<objectRegistry&>(*this).erase(key);
332 }
333 
334 
336 {
337  // Free anything owned by the registry, but first unset both
338  // 'ownedByRegistry' and 'registered' flags to ensure that the
339  // regIOobject destructor will not affect the registry
340 
341  for (iterator iter = begin(); iter != end(); ++iter)
342  {
343  regIOobject* ptr = iter.val();
344 
345  if (ptr && ptr->ownedByRegistry())
346  {
348  {
349  Pout<< "objectRegistry::clear : " << ptr->name() << nl;
350  }
351 
352  ptr->release(true); // Relinquish ownership and registration
353  delete ptr; // Delete also clears fileHandler watches
354  }
355  }
356 
358 }
359 
360 
362 {
365 }
366 
367 
368 bool Foam::objectRegistry::erase(const iterator& iter)
369 {
370  // Remove from registry - see notes in objectRegistry::clear()
371 
372  if (iter.found())
373  {
374  regIOobject* ptr = const_cast<iterator&>(iter).val();
375 
376  const bool ok = HashTable<regIOobject*>::erase(iter);
377 
378  if (ptr && ptr->ownedByRegistry())
379  {
380  ptr->release(true); // Relinquish ownership and registration
381  delete ptr; // Delete also clears fileHandler watches
382  }
383 
384  return ok;
385  }
386 
387  return false;
388 }
389 
390 
392 {
393  return erase(find(key));
394 }
395 
396 
397 Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
398 {
399  return eraseImpl(*this, keys.begin(), keys.end());
400 }
401 
402 
403 Foam::label Foam::objectRegistry::erase(const UList<word>& keys)
404 {
405  return eraseImpl(*this, keys.begin(), keys.end());
406 }
407 
408 
409 void Foam::objectRegistry::rename(const word& newName)
410 {
411  regIOobject::rename(newName);
412 
413  // Adjust dbDir_ as well
414  const auto i = dbDir_.rfind('/');
415 
416  if (i == string::npos)
417  {
418  dbDir_ = newName;
419  }
420  else
421  {
422  dbDir_.replace(i+1, string::npos, newName);
423  }
424 }
425 
426 
428 (
429  const word& name,
430  const bool recursive
431 ) const
432 {
433  return cfindIOobject(name, recursive);
434 }
435 
436 
438 {
439  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
440  {
441  if ((*iter)->modified())
442  {
443  return true;
444  }
445  }
446 
447  return false;
448 }
449 
450 
452 {
453  for (iterator iter = begin(); iter != end(); ++iter)
454  {
456  {
457  Pout<< "objectRegistry::readModifiedObjects() : "
458  << name() << " : Considering reading object "
459  << iter.key() << endl;
460  }
461 
462  (*iter)->readIfModified();
463  }
464 }
465 
466 
468 {
469  readModifiedObjects();
470  return true;
471 }
472 
473 
475 (
476  IOstreamOption streamOpt,
477  const bool valid
478 ) const
479 {
480  bool ok = true;
481 
482  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
483  {
485  {
486  Pout<< "objectRegistry::write() : "
487  << name() << " : Considering writing object "
488  << iter.key()
489  << " of type " << (*iter)->type()
490  << " with writeOpt " << static_cast<int>((*iter)->writeOpt())
491  << " to file " << (*iter)->objectPath()
492  << endl;
493  }
494 
495  if ((*iter)->writeOpt() != NO_WRITE)
496  {
497  ok = (*iter)->writeObject(streamOpt, valid) && ok;
498  }
499  }
500 
501  return ok;
502 }
503 
504 
505 // ************************************************************************* //
Foam::string::replace
string & replace(const std::string &s1, const std::string &s2, size_type pos=0)
Definition: string.C:121
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::HashTable::size
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
Foam::objectRegistry::readIfModified
virtual bool readIfModified()
Read object if modified.
Definition: objectRegistry.C:467
Foam::objectRegistry::sortedNames
wordList sortedNames() const
The sorted names of all objects.
Definition: objectRegistry.C:170
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::objectRegistry::~objectRegistry
virtual ~objectRegistry()
Destructor, with checkOut() for all objects that are ownedByRegistry.
Definition: objectRegistry.C:143
Foam::IOobject::AUTO_WRITE
Definition: IOobject.H:129
Foam::objectRegistry::getEvent
label getEvent() const
Return new event number.
Definition: objectRegistry.C:217
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
stdFoam::begin
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:97
Foam::HashTable::toc
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:121
Foam::regIOobject::release
void release(const bool unregister=false)
Release ownership of this object from its registry.
Definition: regIOobjectI.H:175
Foam::objectRegistry::clearStorage
void clearStorage()
Clear all entries from the registry and the table itself.
Definition: objectRegistry.C:361
validate
thermo validate(args.executable(), "h")
Foam::regIOobject::checkIn
bool checkIn()
Add object to registry, if not already registered.
Definition: regIOobject.C:205
objectRegistry.H
Foam::HashTable::insert
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
Foam::objectRegistry::clear
void clear()
Clear all entries from the registry.
Definition: objectRegistry.C:335
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
erase
srcOptions erase("case")
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::UList::begin
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:276
Foam::regIOobject::store
bool store()
Definition: regIOobjectI.H:37
Foam::predicates::always
Unary and binary predicates that always return true, useful for templating.
Definition: predicates.H:56
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::objectRegistry::rename
virtual void rename(const word &newName)
Rename.
Definition: objectRegistry.C:409
Foam::IOobject::writeOpt
writeOption writeOpt() const
The write option.
Definition: IOobjectI.H:177
Foam::HashTable::erase
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:392
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::objectRegistry::classes
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.
Definition: objectRegistry.C:151
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::objectRegistry::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write the objects using stream options.
Definition: objectRegistry.C:475
Foam::objectRegistry::found
bool found(const word &name, const bool recursive=false) const
Can the regIOobject object be found (by name).
Definition: objectRegistry.C:428
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam::ListOps::find
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Find index of the first occurrence that satisfies the predicate.
Foam::regIOobject::ownedByRegistry
bool ownedByRegistry() const
Is this object owned by the registry?
Definition: regIOobjectI.H:31
Foam::eraseImpl
static label eraseImpl(objectRegistry &obr, InputIter first, InputIter last)
Definition: objectRegistry.C:49
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
stdFoam::cend
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:137
Foam::HashTable::sortedToc
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:136
Foam::HashTable::find
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition: HashTableI.H:114
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::objectRegistry::modified
virtual bool modified() const
Return true if any of the object's files have been modified.
Definition: objectRegistry.C:437
Foam::objectRegistry::readModifiedObjects
void readModifiedObjects()
Read the objects that have been modified.
Definition: objectRegistry.C:451
Time.H
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:71
Foam::objectRegistry::erase
bool erase(const iterator &iter)
Erase an entry specified by the given iterator.
Definition: objectRegistry.C:368
Foam::HashTable::clearStorage
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:649
Foam::regIOobject::checkOut
bool checkOut()
Remove all file watches and remove object from registry.
Definition: regIOobject.C:241
Foam::nl
constexpr char nl
Definition: Ostream.H:385
stdFoam::cbegin
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
Definition: stdFoam.H:113
Foam::HashTable::clear
void clear()
Clear all entries from table.
Definition: HashTable.C:630
Foam::objectRegistry::names
wordList names() const
The names of all objects.
Definition: objectRegistry.C:164
Foam::objectRegistry::subRegistry
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
Definition: objectRegistry.C:191
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::regIOobject::rename
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:432
Foam::List< word >
Foam::UList
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:103
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
predicates.H
Foam::UList::end
iterator end()
Return an iterator to end traversing the UList.
Definition: UListI.H:297
Foam::IOobject::NO_READ
Definition: IOobject.H:123
Foam::objectRegistry::count
label count(const char *clsName) const
The number of objects of the given class name.
Definition: objectRegistry.C:157
constant
constant condensation/saturation model.
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303