mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: avoid unnecessary disk access in writeDictionary (#2362)
- added in special handling for monitoring controlDict. Since controlDict is an unwatchedIOdictionary (not IOdictionary) and not registered either, the usual objectRegistry caching is not available. Instead, access directly from Time. Left the balance of the file handling largely intact (for handling unregistered dictionaries) but could potentially revisit in the future and attempt master-only file access if required. However, most other IOdictionary types will be registered, otherwise the READ_IF_MODIFIED mechanism would not really work properly.
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2013-2017 OpenFOAM Foundation
|
Copyright (C) 2013-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -56,11 +56,10 @@ void Foam::functionObjects::writeDictionary::writeHeader()
|
|||||||
{
|
{
|
||||||
if (firstChange_)
|
if (firstChange_)
|
||||||
{
|
{
|
||||||
Info<< type() << " " << name() << " write:" << nl << endl;
|
|
||||||
|
|
||||||
IOobject::writeDivider(Info);
|
|
||||||
Info<< endl;
|
|
||||||
firstChange_ = false;
|
firstChange_ = false;
|
||||||
|
|
||||||
|
Info<< type() << ' ' << name() << " write:" << nl << nl;
|
||||||
|
IOobject::writeDivider(Info) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,16 +70,16 @@ void Foam::functionObjects::writeDictionary::checkDictionary
|
|||||||
const label dicti
|
const label dicti
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (dict.digest() != digests_[dicti])
|
const auto digest(dict.digest());
|
||||||
|
|
||||||
|
if (digests_[dicti] != digest)
|
||||||
{
|
{
|
||||||
|
digests_[dicti] = digest;
|
||||||
|
|
||||||
writeHeader();
|
writeHeader();
|
||||||
|
dict.writeEntry(Info);
|
||||||
digests_[dicti] = dict.digest();
|
Info<< nl;
|
||||||
|
IOobject::writeDivider(Info) << endl;
|
||||||
Info<< dict.dictName() << dict << nl;
|
|
||||||
|
|
||||||
IOobject::writeDivider(Info);
|
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,13 +120,12 @@ Foam::functionObjects::writeDictionary::writeDictionary
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
regionFunctionObject(name, runTime, dict),
|
functionObjects::regionFunctionObject(name, runTime, dict),
|
||||||
dictNames_(),
|
dictNames_(),
|
||||||
digests_(),
|
digests_(),
|
||||||
firstChange_(true)
|
firstChange_(true)
|
||||||
{
|
{
|
||||||
read(dict);
|
read(dict);
|
||||||
execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -137,21 +135,18 @@ bool Foam::functionObjects::writeDictionary::read(const dictionary& dict)
|
|||||||
{
|
{
|
||||||
regionFunctionObject::read(dict);
|
regionFunctionObject::read(dict);
|
||||||
|
|
||||||
wordList dictNames(dict.get<wordList>("dictNames"));
|
// Make unique
|
||||||
wordHashSet uniqueNames(dictNames);
|
dictNames_ = wordHashSet(dict.get<wordList>("dictNames")).sortedToc();
|
||||||
dictNames_ = uniqueNames.toc();
|
|
||||||
|
|
||||||
digests_.setSize(dictNames_.size(), SHA1Digest());
|
digests_.resize(dictNames_.size());
|
||||||
|
digests_ = SHA1Digest();
|
||||||
|
|
||||||
Info<< type() << " " << name() << ": monitoring dictionaries:" << nl;
|
Info<< type() << ' ' << name() << ": monitoring dictionaries:" << nl;
|
||||||
if (dictNames_.size())
|
for (const word& dictName : dictNames_)
|
||||||
{
|
{
|
||||||
for (const word & dictName : dictNames_)
|
Info<< " " << dictName << nl;
|
||||||
{
|
|
||||||
Info<< " " << dictName << endl;
|
|
||||||
}
|
}
|
||||||
}
|
if (dictNames_.empty())
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Info<< " none" << nl;
|
Info<< " none" << nl;
|
||||||
}
|
}
|
||||||
@ -161,6 +156,53 @@ bool Foam::functionObjects::writeDictionary::read(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::writeDictionary::performCheck()
|
||||||
|
{
|
||||||
|
// Restart reporting cycle
|
||||||
|
firstChange_ = true;
|
||||||
|
|
||||||
|
forAll(dictNames_, dicti)
|
||||||
|
{
|
||||||
|
// Also search parent (eg, Time) as too
|
||||||
|
const auto* dictptr =
|
||||||
|
obr_.cfindObject<IOdictionary>(dictNames_[dicti], true);
|
||||||
|
|
||||||
|
if (dictptr)
|
||||||
|
{
|
||||||
|
checkDictionary(*dictptr, dicti);
|
||||||
|
}
|
||||||
|
else if (dictNames_[dicti] == Time::controlDictName)
|
||||||
|
{
|
||||||
|
// Slight hack. controlDict an unwatchedIOdictionary
|
||||||
|
// (not IOdictionary) and not registered on Time either
|
||||||
|
// - grab directly from Time
|
||||||
|
checkDictionary(obr_.time().controlDict(), dicti);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const bool ok
|
||||||
|
(
|
||||||
|
tryDirectory(obr_.time().timeName(), dicti)
|
||||||
|
|| tryDirectory(obr_.time().constant(), dicti)
|
||||||
|
|| tryDirectory(obr_.time().system(), dicti)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
writeHeader();
|
||||||
|
|
||||||
|
Info<< " Unable to locate dictionary "
|
||||||
|
<< dictNames_[dicti] << nl << nl;
|
||||||
|
|
||||||
|
IOobject::writeDivider(Info) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::functionObjects::writeDictionary::execute()
|
bool Foam::functionObjects::writeDictionary::execute()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -169,44 +211,7 @@ bool Foam::functionObjects::writeDictionary::execute()
|
|||||||
|
|
||||||
bool Foam::functionObjects::writeDictionary::write()
|
bool Foam::functionObjects::writeDictionary::write()
|
||||||
{
|
{
|
||||||
firstChange_ = true;
|
performCheck();
|
||||||
|
|
||||||
forAll(dictNames_, dicti)
|
|
||||||
{
|
|
||||||
const IOdictionary* dictptr =
|
|
||||||
obr_.cfindObject<IOdictionary>(dictNames_[dicti]);
|
|
||||||
|
|
||||||
if (dictptr)
|
|
||||||
{
|
|
||||||
checkDictionary(*dictptr, dicti);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool processed = tryDirectory(obr_.time().timeName(), dicti);
|
|
||||||
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
processed = tryDirectory(obr_.time().constant(), dicti);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
processed = tryDirectory(obr_.time().system(), dicti);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
writeHeader();
|
|
||||||
|
|
||||||
Info<< " Unable to locate dictionary " << dictNames_[dicti]
|
|
||||||
<< nl << endl;
|
|
||||||
|
|
||||||
IOobject::writeDivider(Info);
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2019 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,15 +31,15 @@ Group
|
|||||||
grpUtilitiesFunctionObjects
|
grpUtilitiesFunctionObjects
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Writes dictionaries on start-up and on change.
|
Reports dictionary contents on change.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
writeDictionary.C
|
writeDictionary.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef functionObjects_writeDictionary_H
|
#ifndef Foam_functionObjects_writeDictionary_H
|
||||||
#define functionObjects_writeDictionary_H
|
#define Foam_functionObjects_writeDictionary_H
|
||||||
|
|
||||||
#include "regionFunctionObject.H"
|
#include "regionFunctionObject.H"
|
||||||
#include "wordList.H"
|
#include "wordList.H"
|
||||||
@ -58,18 +58,17 @@ namespace functionObjects
|
|||||||
|
|
||||||
class writeDictionary
|
class writeDictionary
|
||||||
:
|
:
|
||||||
public regionFunctionObject
|
public functionObjects::regionFunctionObject
|
||||||
{
|
{
|
||||||
// Private data
|
// Private Data
|
||||||
|
|
||||||
//- Names of dictionaries to monitor
|
//- Names of dictionaries to monitor
|
||||||
wordList dictNames_;
|
wordList dictNames_;
|
||||||
|
|
||||||
//- List of changed dictionaries (only those registered to database)
|
//- Digest of dictionary contents
|
||||||
List<SHA1Digest> digests_;
|
List<SHA1Digest> digests_;
|
||||||
|
|
||||||
//- Flag to indicate the first time that a dictionary is been changed
|
//- First time that checking has been called (per execution cycle)
|
||||||
//- (per call to execute)
|
|
||||||
bool firstChange_;
|
bool firstChange_;
|
||||||
|
|
||||||
|
|
||||||
@ -81,9 +80,12 @@ class writeDictionary
|
|||||||
//- Helper to check and write the dictionary if its sha1 has changed
|
//- Helper to check and write the dictionary if its sha1 has changed
|
||||||
void checkDictionary(const dictionary& dict, const label dicti);
|
void checkDictionary(const dictionary& dict, const label dicti);
|
||||||
|
|
||||||
//- Helper to write the dictionary if found at location
|
//- Attempt read dictionary at location
|
||||||
bool tryDirectory(const word& location, const label dicti);
|
bool tryDirectory(const word& location, const label dicti);
|
||||||
|
|
||||||
|
//- Check all dictionaries
|
||||||
|
bool performCheck();
|
||||||
|
|
||||||
//- No copy construct
|
//- No copy construct
|
||||||
writeDictionary(const writeDictionary&) = delete;
|
writeDictionary(const writeDictionary&) = delete;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user