Skip to content

Commit 4951d58

Browse files
committed
Avoid const_case by introducing a parsing state
1 parent c759604 commit 4951d58

6 files changed

Lines changed: 56 additions & 44 deletions

File tree

include/openPMD/IO/AbstractIOHandler.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ namespace internal
121121
FlushParams const defaultFlushParams{};
122122

123123
struct ParsedFlushParams;
124+
125+
enum class SeriesStatus : unsigned char
126+
{
127+
Default,
128+
Parsing
129+
};
124130
} // namespace internal
125131

126132
/** Interface for communicating between logical and physically persistent data.
@@ -192,6 +198,7 @@ class AbstractIOHandler
192198
// why do these need to be separate?
193199
Access const m_backendAccess;
194200
Access const m_frontendAccess;
201+
internal::SeriesStatus m_seriesStatus = internal::SeriesStatus::Default;
195202
std::queue<IOTask> m_work;
196203
}; // AbstractIOHandler
197204

include/openPMD/backend/Attributable.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,9 @@ inline bool Attributable::setAttributeImpl(
463463
internal::attr_value_check(key, value, setAttributeMode);
464464

465465
auto &attri = get();
466-
if (IOHandler() && Access::READ_ONLY == IOHandler()->m_frontendAccess)
466+
if (IOHandler() &&
467+
IOHandler()->m_seriesStatus == internal::SeriesStatus::Default &&
468+
Access::READ_ONLY == IOHandler()->m_frontendAccess)
467469
{
468470
auxiliary::OutOfRangeMsg const out_of_range_msg(
469471
"Attribute", "can not be set (read-only).");

include/openPMD/backend/Container.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@ class Container : public Attributable
288288
return it->second;
289289
else
290290
{
291-
if (Access::READ_ONLY == IOHandler()->m_frontendAccess)
291+
if (IOHandler()->m_seriesStatus !=
292+
internal::SeriesStatus::Parsing &&
293+
Access::READ_ONLY == IOHandler()->m_frontendAccess)
292294
{
293295
auxiliary::OutOfRangeMsg const out_of_range_msg;
294296
throw std::out_of_range(out_of_range_msg(key));
@@ -321,7 +323,9 @@ class Container : public Attributable
321323
return it->second;
322324
else
323325
{
324-
if (Access::READ_ONLY == IOHandler()->m_frontendAccess)
326+
if (IOHandler()->m_seriesStatus !=
327+
internal::SeriesStatus::Parsing &&
328+
Access::READ_ONLY == IOHandler()->m_frontendAccess)
325329
{
326330
auxiliary::OutOfRangeMsg out_of_range_msg;
327331
throw std::out_of_range(out_of_range_msg(key));

src/Iteration.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -610,13 +610,10 @@ auto Iteration::beginStep(bool reread) -> BeginStepStatus
610610
case Access::READ_WRITE: {
611611
bool previous = series.iterations.written();
612612
series.iterations.written() = false;
613-
auto oldType = this->IOHandler()->m_frontendAccess;
614-
auto newType =
615-
const_cast<Access *>(&this->IOHandler()->m_frontendAccess);
613+
auto oldStatus = IOHandler()->m_seriesStatus;
614+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Parsing;
616615
res.iterationsInOpenedStep = series.readGorVBased(false);
617-
*newType = Access::READ_WRITE;
618-
series.readGorVBased(false);
619-
*newType = oldType;
616+
IOHandler()->m_seriesStatus = oldStatus;
620617
series.iterations.written() = previous;
621618
break;
622619
}
@@ -734,9 +731,8 @@ void Iteration::runDeferredParseAccess()
734731
}
735732
auto const &deferred = it.m_deferredParseAccess.value();
736733

737-
auto oldAccess = IOHandler()->m_frontendAccess;
738-
auto newAccess = const_cast<Access *>(&IOHandler()->m_frontendAccess);
739-
*newAccess = Access::READ_WRITE;
734+
auto oldStatus = IOHandler()->m_seriesStatus;
735+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Parsing;
740736
try
741737
{
742738
if (deferred.fileBased)
@@ -753,12 +749,12 @@ void Iteration::runDeferredParseAccess()
753749
{
754750
// reset this thing
755751
it.m_deferredParseAccess = std::optional<DeferredParseAccess>();
756-
*newAccess = oldAccess;
752+
IOHandler()->m_seriesStatus = oldStatus;
757753
throw;
758754
}
759755
// reset this thing
760756
it.m_deferredParseAccess = std::optional<DeferredParseAccess>();
761-
*newAccess = oldAccess;
757+
IOHandler()->m_seriesStatus = oldStatus;
762758
break;
763759
}
764760
case Access::CREATE:

src/Series.cpp

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -577,28 +577,34 @@ Given file pattern: ')END"
577577
case Access::READ_WRITE: {
578578
/* Allow creation of values in Containers and setting of Attributes
579579
* Would throw for Access::READ_ONLY */
580-
auto oldType = IOHandler()->m_frontendAccess;
581-
auto newType = const_cast<Access *>(&IOHandler()->m_frontendAccess);
582-
*newType = Access::READ_WRITE;
580+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Parsing;
583581

584-
if (input->iterationEncoding == IterationEncoding::fileBased)
585-
readFileBased();
586-
else
587-
readGorVBased();
588-
589-
if (series.iterations.empty())
582+
try
590583
{
591-
/* Access::READ_WRITE can be used to create a new Series
592-
* allow setting attributes in that case */
593-
written() = false;
584+
if (input->iterationEncoding == IterationEncoding::fileBased)
585+
readFileBased();
586+
else
587+
readGorVBased();
594588

595-
initDefaults(input->iterationEncoding);
596-
setIterationEncoding(input->iterationEncoding);
589+
if (series.iterations.empty())
590+
{
591+
/* Access::READ_WRITE can be used to create a new Series
592+
* allow setting attributes in that case */
593+
written() = false;
597594

598-
written() = true;
595+
initDefaults(input->iterationEncoding);
596+
setIterationEncoding(input->iterationEncoding);
597+
598+
written() = true;
599+
}
600+
}
601+
catch (...)
602+
{
603+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Default;
604+
throw;
599605
}
600606

601-
*newType = oldType;
607+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Default;
602608
break;
603609
}
604610
case Access::CREATE: {
@@ -784,7 +790,7 @@ void Series::flushFileBased(
784790
dirty() |= it->second.dirty();
785791
std::string filename = iterationFilename(it->first);
786792

787-
if(!it->second.written())
793+
if (!it->second.written())
788794
{
789795
series.m_currentlyActiveIterations.emplace(it->first);
790796
}
@@ -1207,19 +1213,18 @@ std::optional<std::deque<uint64_t> > Series::readGorVBased(bool do_init)
12071213
readAttributes(ReadMode::IgnoreExisting);
12081214

12091215
auto withRWAccess = [this](auto &&functor) {
1210-
auto oldType = IOHandler()->m_frontendAccess;
1211-
auto newType = const_cast<Access *>(&IOHandler()->m_frontendAccess);
1212-
*newType = Access::READ_WRITE;
1216+
auto oldStatus = IOHandler()->m_seriesStatus;
1217+
IOHandler()->m_seriesStatus = internal::SeriesStatus::Parsing;
12131218
try
12141219
{
12151220
std::forward<decltype(functor)>(functor)();
12161221
}
12171222
catch (...)
12181223
{
1219-
*newType = oldType;
1224+
IOHandler()->m_seriesStatus = oldStatus;
12201225
throw;
12211226
}
1222-
*newType = oldType;
1227+
IOHandler()->m_seriesStatus = oldStatus;
12231228
};
12241229

12251230
/*
@@ -1234,7 +1239,7 @@ std::optional<std::deque<uint64_t> > Series::readGorVBased(bool do_init)
12341239
IOHandler()->enqueue(IOTask(&series.iterations, pList));
12351240
IOHandler()->flush(internal::defaultFlushParams);
12361241

1237-
auto readSingleIteration = [&series, &pOpen, this](
1242+
auto readSingleIteration = [&series, &pOpen, this, withRWAccess](
12381243
uint64_t index,
12391244
std::string path,
12401245
bool guardAgainstRereading,
@@ -1253,12 +1258,7 @@ std::optional<std::deque<uint64_t> > Series::readGorVBased(bool do_init)
12531258
{
12541259
pOpen.path = path;
12551260
IOHandler()->enqueue(IOTask(&i, pOpen));
1256-
auto oldType = IOHandler()->m_frontendAccess;
1257-
auto newType =
1258-
const_cast<Access *>(&IOHandler()->m_frontendAccess);
1259-
*newType = Access::READ_WRITE;
1260-
i.reread(path);
1261-
*newType = oldType;
1261+
withRWAccess([&i, &path]() { i.reread(path); });
12621262
}
12631263
}
12641264
else
@@ -1622,7 +1622,8 @@ AdvanceStatus Series::advance(
16221622
void Series::flushStep(bool doFlush)
16231623
{
16241624
auto &series = get();
1625-
if (!series.m_currentlyActiveIterations.empty())
1625+
if (!series.m_currentlyActiveIterations.empty() &&
1626+
IOHandler()->m_frontendAccess != Access::READ_ONLY)
16261627
{
16271628
/*
16281629
* Warning: changing attribute extents over time (probably) unsupported

test/SerialIOTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6463,6 +6463,8 @@ void append_mode(
64636463
uint64_t iterationOrder[] = {0, 1, 2, 3, 4, 10, 7, 11};
64646464
for (auto const &iteration : read.readIterations())
64656465
{
6466+
std::cout << "Seeing iteration " << iteration.iterationIndex
6467+
<< " of series " << filename << std::endl;
64666468
REQUIRE(iteration.iterationIndex == iterationOrder[counter]);
64676469
++counter;
64686470
}

0 commit comments

Comments
 (0)