Loading...
Searching...
No Matches
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-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
35namespace Foam
36{
38}
39
40
41// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
43namespace Foam
44{
45
46// Templated implementation for erase() with iterator range.
47// Prefer not to expose directly.
48template<class InputIter>
49static 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
74bool Foam::objectRegistry::parentNotTime() const noexcept
76 return (&parent_ != static_cast<const objectRegistry*>(&time_));
77}
78
79
80// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81
82Foam::objectRegistry::objectRegistry
83(
84 const Time& t,
85 const label initialCapacity
86)
87:
89 (
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
112Foam::objectRegistry::objectRegistry
113(
114 const IOobject& io,
115 const label initialCapacity
116)
117:
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)
131
132// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
133
137}
138
139
140// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
143{
144 return (this == &static_cast<const objectRegistry&>(time_));
145}
146
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
208Foam::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
218}
219
225
226
228{
229 // No nullptr check - only called with string literals
230 return names(static_cast<word>(clsName));
231}
232
233
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 (
253 (
254 name,
255 time().constant(),
256 *this,
260 )
261 );
262 subObr->store();
263 }
264
265 return lookupObject<objectRegistry>(name, recursive);
266}
267
268
269Foam::label Foam::objectRegistry::getEvent() const
270{
271 label curEvent = event_++;
272
273 if (event_ == labelMax)
274 {
275 if (objectRegistry::debug)
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
295bool Foam::objectRegistry::checkIn(regIOobject* io) const
296{
297 if (!io) return false;
298
299 objectRegistry& obr = const_cast<objectRegistry&>(*this);
300
301 if (objectRegistry::debug)
302 {
303 Pout<< "objectRegistry::checkIn : "
304 << name() << " : checking in " << io->name()
305 << " 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 {
326 if (objectRegistry::debug)
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"
348 }
349
350 return ok;
351}
352
353
354bool 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 {
364 if (objectRegistry::debug)
365 {
366 Pout<< "objectRegistry::checkOut : "
367 << name() << " : checking out " << io->name()
368 << " type=" << io->type()
369 << " owned=" << io->ownedByRegistry()
370 << endl;
371 }
372
373 if (iter.val() != io)
374 {
375 if (objectRegistry::debug)
376 {
378 << name() << " : Attempt to checkOut copy of "
379 << iter.key()
380 << endl;
381 }
382
383 return false;
384 }
385
386 return obr.erase(iter);
387 }
388
389
390 if (objectRegistry::debug)
391 {
392 Pout<< "objectRegistry::checkOut : "
393 << name() << " : could not find " << io->name() << " in registry"
395 }
396
397 return false;
398}
399
402{
403 return checkIn(&io);
404}
405
408{
409 return checkOut(&io);
410}
411
413bool Foam::objectRegistry::checkOut(const word& key) const
414{
415 return const_cast<objectRegistry&>(*this).erase(key);
416}
417
418
420{
421 // Free anything owned by the registry, but first unset both
422 // 'ownedByRegistry' and 'registered' flags to ensure that the
423 // regIOobject destructor will not affect the registry
424
425 for (iterator iter = begin(); iter != end(); ++iter)
426 {
427 regIOobject* ptr = iter.val();
428
429 if (ptr && ptr->ownedByRegistry())
430 {
431 if (objectRegistry::debug)
432 {
433 Pout<< "objectRegistry::clear : " << ptr->name() << nl;
434 }
435
436 ptr->release(true); // Relinquish ownership and registration
437 delete ptr; // Delete also clears fileHandler watches
439 }
440
442}
443
444
446{
449}
450
451
453{
454 // Remove from registry - see notes in objectRegistry::clear()
455
456 if (iter.good())
457 {
458 regIOobject* ptr = const_cast<iterator&>(iter).val();
459
460 const bool ok = HashTable<regIOobject*>::erase(iter);
461
462 if (ptr && ptr->ownedByRegistry())
463 {
464 ptr->release(true); // Relinquish ownership and registration
465 delete ptr; // Delete also clears fileHandler watches
466 }
467
468 return ok;
469 }
470
471 return false;
472}
473
475bool Foam::objectRegistry::erase(const word& key)
476{
477 return erase(find(key));
478}
479
481Foam::label Foam::objectRegistry::erase(std::initializer_list<word> keys)
482{
483 return eraseImpl(*this, keys.begin(), keys.end());
484}
485
488{
489 return eraseImpl(*this, keys.begin(), keys.end());
490}
491
492
493void Foam::objectRegistry::rename(const word& newName)
494{
495 regIOobject::rename(newName);
496
497 // Adjust dbDir_ as well
498 const auto i = dbDir_.rfind('/');
499
500 if (i == string::npos)
501 {
502 dbDir_ = newName;
503 }
504 else
505 {
506 dbDir_.replace(i+1, string::npos, newName);
507 }
508}
509
510
512(
513 const word& name,
514 const bool recursive
515) const
516{
517 if (name.empty())
518 {
519 return nullptr;
520 }
521 else if (auto iter = cfind(name); iter.good())
522 {
523 return iter.val();
524 }
525 else if (recursive && !this->isTimeDb())
526 {
527 return parent_.cfindIOobject(name, recursive);
528 }
529
530 return nullptr;
531}
532
533
535(
536 const word& name,
537 const bool recursive
538) const
539{
540 return cfindIOobject(name, recursive);
541}
542
543
545{
546 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
547 {
548 if (iter.val()->modified())
549 {
550 return true;
552 }
553
554 return false;
555}
556
557
559{
560 for (iterator iter = begin(); iter != end(); ++iter)
561 {
562 if (objectRegistry::debug)
563 {
564 Pout<< "objectRegistry::readModifiedObjects() : "
565 << name() << " : Considering reading object "
566 << iter.key() << endl;
568
569 iter.val()->readIfModified();
570 }
571}
572
573
575{
577 return true;
578}
579
580
582(
583 IOstreamOption streamOpt,
584 const bool writeOnProc
585) const
586{
587 bool ok = true;
588
589 for (const_iterator iter = cbegin(); iter != cend(); ++iter)
590 {
591 if (objectRegistry::debug)
592 {
593 const regIOobject& obj = *iter.val();
594
595 Pout<< "objectRegistry::write() : "
596 << name() << " : Considering writing object "
597 << iter.key() << " type="
598 << obj.type() << " writeOpt="
599 << static_cast<int>(obj.writeOpt())
600 << " to file " << obj.objectRelPath() << endl;
601 }
602
603 if (iter.val()->writeOpt() != IOobjectOption::NO_WRITE)
604 {
605 ok = iter.val()->writeObject(streamOpt, writeOnProc) && ok;
606 }
607 }
608
609 return ok;
610}
611
612
613// ************************************************************************* //
A HashTable similar to std::unordered_map.
Definition HashTable.H:124
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition HashTable.C:156
const_iterator_pair< const_key_iterator, this_type > keys() const
Definition HashTable.H:1295
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition HashTable.C:141
const_iterator cbegin() const
const_iterator cfind(const word &key) const
Definition HashTableI.H:113
void clearStorage()
Remove all entries from table and the table itself.
Definition HashTable.C:767
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition HashTableI.H:152
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition HashTableI.H:86
label size() const noexcept
The number of elements in table.
Definition HashTable.H:358
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition HashTable.C:489
void clear()
Remove all entries from table.
Definition HashTable.C:742
constexpr const_iterator cend() const noexcept
constexpr HashTable() noexcept
Definition HashTable.C:33
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
registerOption
Enumeration for use with registerObject(). Values map to bool (false/true).
@ NO_REGISTER
Do not request registration (bool: false).
@ REGISTER
Request registration (bool: true).
writeOption writeOpt() const noexcept
Get the write option.
readOption
Enumeration defining read preferences.
@ NO_READ
Nothing to be read.
writeOption
Enumeration defining write preferences.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition IOobject.C:450
const fileName & local() const noexcept
Read access to local path component.
Definition IOobjectI.H:301
fileName objectRelPath() const
The object path relative to the case.
Definition IOobject.C:581
fileName path() const
The complete path for the object (with instance, local,...).
Definition IOobject.C:500
const fileName & caseName() const noexcept
Return the Time::caseName().
Definition IOobject.C:468
A simple container for options an IOstream can normally have.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
label find(const T &val) const
Find index of the first occurrence of the value.
Definition UList.C:160
Registry of regIOobjects.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write the objects using stream options.
bool contains(const word &name, const bool recursive=false) const
Does the registry contain the regIOobject object (by name).
bool foundObject(const word &name, const bool recursive=false) const
Contains the named Type?
bool checkIn(regIOobject *io) const
Add a regIOobject to registry. A nullptr is ignored.
wordList sortedNames() const
The sorted names of all objects.
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
virtual bool modified() const
Return true if any of the object's files have been modified.
bool isTimeDb() const noexcept
True if the registry is Time.
HashTable< wordHashSet > classes() const
A summary hash of classes used and their associated object names.
virtual ~objectRegistry()
Destructor, with checkOut() for all objects that are ownedByRegistry.
const Time & time() const noexcept
Return time registry.
void clearStorage()
Clear all entries from the registry and the table itself.
IOobject newIOobject(const word &name, IOobjectOption ioOpt) const
Create an IOobject at the current time instance (timeName) with the specified options.
const regIOobject * cfindIOobject(const word &name, const bool recursive=false) const
Return const pointer to the regIOobject.
virtual bool readIfModified()
Read object if modified.
bool checkOut(regIOobject *io) const
Remove a regIOobject from registry and free memory if the object is ownedByRegistry....
bool erase(const iterator &iter)
Erase an entry specified by the given iterator.
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
void clear()
Clear all entries from the registry.
void readModifiedObjects()
Read the objects that have been modified.
wordList names() const
The unsorted names of all objects.
label count(const char *clsName) const
The number of objects of the given class name.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
virtual void rename(const word &newName)
Rename.
label getEvent() const
Return new event number.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition regIOobject.H:71
regIOobject(const IOobject &io, const bool isTimeObject=false)
Construct from IOobject. The optional flag adds special handling if the object is the top-level regIO...
Definition regIOobject.C:43
bool ownedByRegistry() const noexcept
Is this object owned by the registry?
bool store()
Register object with its registry and transfer ownership to the registry.
bool checkOut()
Remove object from registry, and remove all file watches.
void release(const bool unregister=false) noexcept
Set object as not ownedByRegistry.
virtual void rename(const word &newName)
Rename.
bool checkIn()
Add object to registry, if not already registered.
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
bool local
Definition EEqn.H:20
const auto & io
auto & name
auto & names
word timeName
Definition getTimeIndex.H:3
#define WarningInFunction
Report a warning using Foam::Warning.
const char * end
Definition SVGTools.H:223
Different types of constants.
Namespace for OpenFOAM.
static label eraseImpl(objectRegistry &obr, InputIter first, InputIter last)
List< word > wordList
List of word.
Definition fileName.H:60
constexpr label labelMax
Definition label.H:55
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
const direction noexcept
Definition scalarImpl.H:265
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
srcOptions erase("case")
thermo validate(args.executable(), "h")
Unary and binary predicates that always return true, useful for templating.
Definition predicates.H:54