Skip to content

Commit ec2d404

Browse files
committed
Reload config when reading from a JSON file
1 parent 2d59c0f commit ec2d404

File tree

2 files changed

+90
-8
lines changed

2 files changed

+90
-8
lines changed

include/openPMD/IO/JSON/JSONIOHandlerImpl.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,15 @@ class JSONIOHandlerImpl : public AbstractIOHandlerImpl
410410

411411
std::string m_originalExtension;
412412

413+
/*
414+
* In read mode, we can only open the external block storage backend upon
415+
* opening the JSON file, because it contains meta information relevant
416+
* for configuring the backend.
417+
*/
418+
std::optional<openPMD::json::TracingJSON>
419+
m_deferredExternalBlockstorageConfig;
413420
DatasetMode_s m_datasetMode;
414-
DatasetMode_s retrieveDatasetMode(openPMD::json::TracingJSON &config) const;
421+
DatasetMode_s retrieveDatasetMode(openPMD::json::TracingJSON &config);
415422

416423
AttributeMode_s m_attributeMode;
417424
AttributeMode_s

src/IO/JSON/JSONIOHandlerImpl.cpp

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "openPMD/Error.hpp"
2525
#include "openPMD/IO/AbstractIOHandler.hpp"
2626
#include "openPMD/IO/AbstractIOHandlerImpl.hpp"
27+
#include "openPMD/IO/Access.hpp"
2728
#include "openPMD/ThrowError.hpp"
2829
#include "openPMD/auxiliary/Filesystem.hpp"
2930
#include "openPMD/auxiliary/JSONMatcher.hpp"
@@ -349,8 +350,8 @@ namespace
349350

350351
auto get_mandatory = [&](char const *key,
351352
bool lowercase) -> std::string {
352-
auto const &val = *optionalOrElse(
353-
get_key("mode"), [&]() -> nlohmann::json const * {
353+
auto const &val =
354+
*optionalOrElse(get_key(key), [&]() -> nlohmann::json const * {
354355
throw error::BackendConfigSchema(
355356
{configLocation, "mode", key}, "Mandatory key.");
356357
});
@@ -394,7 +395,7 @@ namespace
394395
}
395396
static_cast<decltype(then)>(then)(val.get<bool>());
396397
};
397-
auto modeString = get_mandatory("type", true);
398+
auto modeString = get_mandatory("provider", true);
398399

399400
if (modeString == "stdio")
400401
{
@@ -465,8 +466,8 @@ namespace
465466
}
466467
} // namespace
467468

468-
auto JSONIOHandlerImpl::retrieveDatasetMode(
469-
openPMD::json::TracingJSON &config) const -> DatasetMode_s
469+
auto JSONIOHandlerImpl::retrieveDatasetMode(openPMD::json::TracingJSON &config)
470+
-> DatasetMode_s
470471
{
471472
// start with / copy from current config
472473
auto res = m_datasetMode;
@@ -484,8 +485,20 @@ auto JSONIOHandlerImpl::retrieveDatasetMode(
484485
auto mode = datasetConfig["mode"];
485486
if (mode.json().is_object())
486487
{
487-
parse_external_mode(
488-
std::move(mode), std::nullopt, configLocation, res);
488+
if (access::writeOnly(m_handler->m_backendAccess))
489+
{
490+
parse_external_mode(
491+
std::move(mode), std::nullopt, configLocation, res);
492+
}
493+
else
494+
{
495+
// sic! initialize the deferred json config as a new
496+
// tracing object
497+
m_deferredExternalBlockstorageConfig =
498+
std::make_optional<openPMD::json::TracingJSON>(
499+
config.json(), config.originallySpecifiedAs);
500+
config.declareFullyRead();
501+
}
489502
}
490503
else
491504
{
@@ -661,6 +674,14 @@ void JSONIOHandlerImpl::createFile(
661674
access::write(m_handler->m_backendAccess),
662675
"[JSON] Creating a file in read-only mode is not possible.");
663676

677+
if (m_deferredExternalBlockstorageConfig.has_value())
678+
{
679+
throw error::Internal(
680+
"Creation of external block storage backend was deferred until "
681+
"opening the first file, but a file is created before any was "
682+
"opened.");
683+
}
684+
664685
/*
665686
* Need to resolve this later than init() since the openPMD version might be
666687
* specified after the creation of the IOHandler.
@@ -1104,6 +1125,28 @@ void JSONIOHandlerImpl::openFile(
11041125

11051126
auto file = std::get<0>(getPossiblyExisting(name));
11061127

1128+
if (m_deferredExternalBlockstorageConfig.has_value())
1129+
{
1130+
auto const &contents = obtainJsonContents(file);
1131+
auto previousConfig = [&]() -> std::optional<nlohmann::json const *> {
1132+
if (contents->contains("external_storage"))
1133+
{
1134+
return std::make_optional<nlohmann::json const *>(
1135+
&contents->at("external_storage"));
1136+
}
1137+
else
1138+
{
1139+
return std::nullopt;
1140+
}
1141+
}();
1142+
parse_external_mode(
1143+
std::move(*m_deferredExternalBlockstorageConfig),
1144+
previousConfig,
1145+
backendConfigKey(),
1146+
m_datasetMode);
1147+
m_attributeMode.m_specificationVia = SpecificationVia::Manually;
1148+
}
1149+
11071150
associateWithFile(writable, file);
11081151

11091152
writable->written = true;
@@ -2242,6 +2285,9 @@ JSONIOHandlerImpl::obtainJsonContents(File const &file)
22422285
auto res = serialImplementation();
22432286
#endif
22442287

2288+
bool initialize_external_block_storage =
2289+
m_deferredExternalBlockstorageConfig.has_value();
2290+
22452291
if (res->contains(JSONDefaults::openpmd_internal))
22462292
{
22472293
auto const &openpmd_internal = res->at(JSONDefaults::openpmd_internal);
@@ -2272,6 +2318,10 @@ JSONIOHandlerImpl::obtainJsonContents(File const &file)
22722318
{
22732319
m_datasetMode.m_mode = DatasetMode::Template;
22742320
}
2321+
else if (modeOption.value() == "external")
2322+
{
2323+
initialize_external_block_storage = true;
2324+
}
22752325
else
22762326
{
22772327
std::cerr << "[JSON/TOML backend] Warning: Invalid value '"
@@ -2315,6 +2365,31 @@ JSONIOHandlerImpl::obtainJsonContents(File const &file)
23152365
}
23162366
}
23172367
}
2368+
2369+
if (initialize_external_block_storage)
2370+
{
2371+
auto previousConfig = [&]() -> std::optional<nlohmann::json const *> {
2372+
if (res->contains("external_storage"))
2373+
{
2374+
return std::make_optional<nlohmann::json const *>(
2375+
&res->at("external_storage"));
2376+
}
2377+
else
2378+
{
2379+
return std::nullopt;
2380+
}
2381+
}();
2382+
parse_external_mode(
2383+
m_deferredExternalBlockstorageConfig.has_value()
2384+
? std::move(*m_deferredExternalBlockstorageConfig)
2385+
: openPMD::json::TracingJSON(),
2386+
previousConfig,
2387+
backendConfigKey(),
2388+
m_datasetMode);
2389+
m_attributeMode.m_specificationVia = SpecificationVia::Manually;
2390+
m_deferredExternalBlockstorageConfig.reset();
2391+
}
2392+
23182393
m_jsonVals.emplace(file, res);
23192394
return res;
23202395
}

0 commit comments

Comments
 (0)