diff --git a/include/openPMD/IO/IOTask.hpp b/include/openPMD/IO/IOTask.hpp index 8ded6f1775..227957f857 100644 --- a/include/openPMD/IO/IOTask.hpp +++ b/include/openPMD/IO/IOTask.hpp @@ -30,6 +30,7 @@ #include "openPMD/backend/Attribute.hpp" #include "openPMD/backend/ParsePreference.hpp" +#include #include #include #include @@ -209,6 +210,8 @@ struct OPENPMDAPI_EXPORT Parameter Parameter &operator=(Parameter &&) = default; Parameter &operator=(Parameter const &) = default; + std::any keep_this_data_alive; + std::unique_ptr to_heap() && override { return std::unique_ptr( diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 49e8c3296c..02fd224e1e 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -397,6 +397,8 @@ class Iteration : public Attributable * */ void runDeferredParseAccess(); + + Iteration resetIteration(); }; // Iteration extern template float Iteration::time() const; diff --git a/src/Iteration.cpp b/src/Iteration.cpp index 614c2bd260..5eb6bce18c 100644 --- a/src/Iteration.cpp +++ b/src/Iteration.cpp @@ -866,6 +866,22 @@ void Iteration::linkHierarchy(Writable &w) Attributable::linkHierarchy(w); meshes.linkHierarchy(this->writable()); particles.linkHierarchy(this->writable()); + meshes.writable().ownKeyWithinParent = {"meshes"}; + particles.writable().ownKeyWithinParent = {"particles"}; +} + +Iteration Iteration::resetIteration() +{ + Iteration copied = *this; + auto parent = writable().parent; + + setData(std::make_shared()); + meshes = {}; + particles = {}; + writable().written = true; + + this->linkHierarchy(*parent); + return copied; } void Iteration::runDeferredParseAccess() diff --git a/src/ReadIterations.cpp b/src/ReadIterations.cpp index 9457a22421..9662cb489c 100644 --- a/src/ReadIterations.cpp +++ b/src/ReadIterations.cpp @@ -529,8 +529,10 @@ void SeriesIterator::deactivateDeadIteration(iteration_index_t index) { case IterationEncoding::fileBased: { Parameter param; - data.series->IOHandler()->enqueue( - IOTask(&data.series->iterations[index], std::move(param))); + Iteration resetted = data.series->iterations[index].resetIteration(); + auto writable = &resetted.writable(); + param.keep_this_data_alive = std::move(resetted); + data.series->IOHandler()->enqueue(IOTask(writable, std::move(param))); data.series->IOHandler()->flush({FlushLevel::UserFlush}); } break; diff --git a/src/Series.cpp b/src/Series.cpp index b7c807eb4c..da638ce2ee 100644 --- a/src/Series.cpp +++ b/src/Series.cpp @@ -780,7 +780,10 @@ void Series::flushFileBased( internal::CloseStatus::ClosedInFrontend) { Parameter fClose; - IOHandler()->enqueue(IOTask(&it->second, std::move(fClose))); + Iteration resetted = it->second.resetIteration(); + auto writable = &resetted.writable(); + fClose.keep_this_data_alive = std::move(resetted); + IOHandler()->enqueue(IOTask(writable, std::move(fClose))); it->second.get().m_closed = internal::CloseStatus::ClosedInBackend; } @@ -838,7 +841,10 @@ void Series::flushFileBased( internal::CloseStatus::ClosedInFrontend) { Parameter fClose; - IOHandler()->enqueue(IOTask(&it->second, std::move(fClose))); + Iteration resetted = it->second.resetIteration(); + auto writable = &resetted.writable(); + fClose.keep_this_data_alive = std::move(resetted); + IOHandler()->enqueue(IOTask(writable, std::move(fClose))); it->second.get().m_closed = internal::CloseStatus::ClosedInBackend; } @@ -1876,7 +1882,10 @@ AdvanceStatus Series::advance( if (itData.m_closed != internal::CloseStatus::ClosedTemporarily) { Parameter fClose; - IOHandler()->enqueue(IOTask(&iteration, std::move(fClose))); + Iteration resetted = iteration.resetIteration(); + auto writable = &resetted.writable(); + fClose.keep_this_data_alive = std::move(resetted); + IOHandler()->enqueue(IOTask(writable, std::move(fClose))); } itData.m_closed = internal::CloseStatus::ClosedInBackend; break; diff --git a/test/SerialIOTest.cpp b/test/SerialIOTest.cpp index e3cb2ea2a2..53e6007c72 100644 --- a/test/SerialIOTest.cpp +++ b/test/SerialIOTest.cpp @@ -6833,13 +6833,13 @@ void varying_pattern(std::string const &file_ending) REQUIRE(it.getAttribute("my_step").get() == int(step)); } - helper::listSeries(series, true, std::cout); - for (auto i : {0, 8000, 10000, 100000, 2000000}) { auto it = series.iterations[i]; REQUIRE(it.getAttribute("my_step").get() == i); } + + helper::listSeries(series, true, std::cout); } }