|
6 | 6 | #include "openPMD/snapshots/IteratorHelpers.hpp" |
7 | 7 | #include "openPMD/snapshots/RandomAccessIterator.hpp" |
8 | 8 | #include "openPMD/snapshots/StatefulIterator.hpp" |
| 9 | +#include <cassert> |
9 | 10 | #include <memory> |
10 | 11 | #include <optional> |
11 | 12 | #include <stdexcept> |
@@ -209,94 +210,82 @@ auto StatefulSnapshotsContainer::operator[](key_type const &key) |
209 | 210 | { |
210 | 211 | throw std::runtime_error("Stateful iteration on a read-write Series."); |
211 | 212 | } |
212 | | - if (access::write(access)) |
| 213 | + else if ( |
| 214 | + access::read(access) || |
| 215 | + s.series.iterations.find(key) != s.series.iterations.end()) |
213 | 216 | { |
214 | | - if (auto it = s.series.iterations.find(key); |
215 | | - it != s.series.iterations.end()) |
| 217 | + return at(key); |
| 218 | + } |
| 219 | + |
| 220 | + assert(access::write(access)); |
| 221 | + |
| 222 | + auto lastIteration = base_iterator->peekCurrentlyOpenIteration(); |
| 223 | + if (lastIteration.has_value()) |
| 224 | + { |
| 225 | + auto lastIteration_v = lastIteration.value(); |
| 226 | + if (lastIteration_v->first == key) |
216 | 227 | { |
217 | | - return at(key); |
| 228 | + return s.series.iterations.at(key); |
218 | 229 | } |
219 | | - auto lastIteration = base_iterator->peekCurrentlyOpenIteration(); |
220 | | - if (lastIteration.has_value()) |
| 230 | + else |
221 | 231 | { |
222 | | - auto lastIteration_v = lastIteration.value(); |
223 | | - if (lastIteration_v->first == key) |
224 | | - { |
225 | | - return s.series.iterations.at(key); |
226 | | - } |
227 | | - else |
228 | | - { |
229 | | - lastIteration_v->second.close(); // continue below |
230 | | - } |
| 232 | + lastIteration_v->second.close(); // continue below |
231 | 233 | } |
| 234 | + } |
232 | 235 |
|
233 | | - // create new |
234 | | - auto &res = s.series.iterations[key]; |
235 | | - Iteration::BeginStepStatus status = [&]() { |
236 | | - try |
| 236 | + // create new |
| 237 | + auto &res = s.series.iterations[key]; |
| 238 | + Iteration::BeginStepStatus status = [&]() { |
| 239 | + try |
| 240 | + { |
| 241 | + return res.beginStep(/* reread = */ false); |
| 242 | + } |
| 243 | + catch (error::OperationUnsupportedInBackend const &) |
| 244 | + { |
| 245 | + s.series.iterations.retrieveSeries() |
| 246 | + .get() |
| 247 | + .m_currentlyActiveIterations.clear(); |
| 248 | + throw; |
| 249 | + } |
| 250 | + }(); |
| 251 | + res.setStepStatus(StepStatus::DuringStep); |
| 252 | + |
| 253 | + s.currentStep.map_during_t( |
| 254 | + [&](detail::CurrentStep::During_t &during) { |
| 255 | + switch (status.stepStatus) |
237 | 256 | { |
238 | | - return res.beginStep(/* reread = */ false); |
| 257 | + case AdvanceStatus::OK: |
| 258 | + ++during.step_count; |
| 259 | + during.available_iterations_in_step = {key}; |
| 260 | + break; |
| 261 | + case AdvanceStatus::RANDOMACCESS: |
| 262 | + during.available_iterations_in_step.emplace_back(key); |
| 263 | + break; |
| 264 | + case AdvanceStatus::OVER: |
| 265 | + throw error::Internal( |
| 266 | + "Backend reported OVER status while trying to create " |
| 267 | + "new Iteration."); |
239 | 268 | } |
240 | | - catch (error::OperationUnsupportedInBackend const &) |
| 269 | + base_iterator->get().seen_iterations[key] = during.step_count; |
| 270 | + during.iteration_idx = key; |
| 271 | + }, |
| 272 | + [&](detail::CurrentStep::AtTheEdge where_am_i) |
| 273 | + -> detail::CurrentStep::During_t { |
| 274 | + base_iterator->get().seen_iterations[key] = 0; |
| 275 | + switch (where_am_i) |
241 | 276 | { |
242 | | - s.series.iterations.retrieveSeries() |
243 | | - .get() |
244 | | - .m_currentlyActiveIterations.clear(); |
245 | | - throw; |
| 277 | + case detail::CurrentStep::AtTheEdge::Begin: |
| 278 | + return detail::CurrentStep::During_t{0, key, {key}}; |
| 279 | + case detail::CurrentStep::AtTheEdge::End: |
| 280 | + throw error::Internal( |
| 281 | + "Trying to create a new output step, but the " |
| 282 | + "stream is " |
| 283 | + "closed?"); |
246 | 284 | } |
247 | | - }(); |
248 | | - res.setStepStatus(StepStatus::DuringStep); |
249 | | - |
250 | | - s.currentStep.map_during_t( |
251 | | - [&](detail::CurrentStep::During_t &during) { |
252 | | - switch (status.stepStatus) |
253 | | - { |
254 | | - case AdvanceStatus::OK: |
255 | | - ++during.step_count; |
256 | | - during.available_iterations_in_step = {key}; |
257 | | - break; |
258 | | - case AdvanceStatus::RANDOMACCESS: |
259 | | - during.available_iterations_in_step.emplace_back(key); |
260 | | - break; |
261 | | - case AdvanceStatus::OVER: |
262 | | - throw error::Internal( |
263 | | - "Backend reported OVER status while trying to create " |
264 | | - "new Iteration."); |
265 | | - } |
266 | | - base_iterator->get().seen_iterations[key] = during.step_count; |
267 | | - during.iteration_idx = key; |
268 | | - }, |
269 | | - [&](detail::CurrentStep::AtTheEdge where_am_i) |
270 | | - -> detail::CurrentStep::During_t { |
271 | | - base_iterator->get().seen_iterations[key] = 0; |
272 | | - switch (where_am_i) |
273 | | - { |
274 | | - case detail::CurrentStep::AtTheEdge::Begin: |
275 | | - return detail::CurrentStep::During_t{0, key, {key}}; |
276 | | - case detail::CurrentStep::AtTheEdge::End: |
277 | | - throw error::Internal( |
278 | | - "Trying to create a new output step, but the " |
279 | | - "stream is " |
280 | | - "closed?"); |
281 | | - } |
282 | | - throw std::runtime_error("Unreachable!"); |
283 | | - }); |
284 | | - |
285 | | - return res; |
286 | | - } |
287 | | - else if (access::read(access)) |
288 | | - { |
289 | | - auto &result = base_iterator->seek( |
290 | | - {StatefulIterator::Seek::Seek_Iteration_t{key}}); |
291 | | - if (result.is_end()) |
292 | | - { |
293 | | - throw std::out_of_range( |
294 | | - "[StatefulSnapshotsContainer::operator[]()] Cannot (yet) skip " |
295 | | - "to a Snapshot from an I/O step that is not active."); |
296 | | - } |
297 | | - return result->second; |
298 | | - } |
299 | | - throw error::Internal("Control flow error: This should be unreachable."); |
| 285 | + throw std::runtime_error("Unreachable!"); |
| 286 | + }); |
| 287 | + |
| 288 | + return res; |
300 | 289 | } |
301 | 290 |
|
302 | 291 | auto StatefulSnapshotsContainer::clear() -> void |
|
0 commit comments