forked from openPMD/openPMD-api
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAbstractIOHandlerImpl.hpp
More file actions
320 lines (308 loc) · 18.2 KB
/
AbstractIOHandlerImpl.hpp
File metadata and controls
320 lines (308 loc) · 18.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* Copyright 2018-2020 Fabian Koller
*
* This file is part of openPMD-api.
*
* openPMD-api is free software: you can redistribute it and/or modify
* it under the terms of of either the GNU General Public License or
* the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* openPMD-api is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with openPMD-api.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "openPMD/IO/AbstractIOHandler.hpp"
#include "openPMD/IO/IOTask.hpp"
#include "openPMD/auxiliary/DerefDynamicCast.hpp"
#include <future>
namespace openPMD
{
// class AbstractIOHandler;
class Writable;
class AbstractIOHandlerImpl
{
public:
AbstractIOHandlerImpl(AbstractIOHandler *handler)
: m_handler{handler}
{ }
virtual ~AbstractIOHandlerImpl() = default;
virtual std::future< void > flush()
{
using namespace auxiliary;
while( !(*m_handler).m_work.empty() )
{
IOTask& i = (*m_handler).m_work.front();
try
{
switch( i.operation )
{
using O = Operation;
case O::CREATE_FILE:
createFile(i.writable, deref_dynamic_cast< Parameter< Operation::CREATE_FILE > >(i.parameter.get()));
break;
case O::CREATE_PATH:
createPath(i.writable, deref_dynamic_cast< Parameter< O::CREATE_PATH > >(i.parameter.get()));
break;
case O::CREATE_DATASET:
createDataset(i.writable, deref_dynamic_cast< Parameter< O::CREATE_DATASET > >(i.parameter.get()));
break;
case O::EXTEND_DATASET:
extendDataset(i.writable, deref_dynamic_cast< Parameter< O::EXTEND_DATASET > >(i.parameter.get()));
break;
case O::OPEN_FILE:
openFile(i.writable, deref_dynamic_cast< Parameter< O::OPEN_FILE > >(i.parameter.get()));
break;
case O::CLOSE_FILE:
closeFile(i.writable, *dynamic_cast< Parameter< O::CLOSE_FILE >* >(i.parameter.get()));
break;
case O::OPEN_PATH:
openPath(i.writable, deref_dynamic_cast< Parameter< O::OPEN_PATH > >(i.parameter.get()));
break;
case O::OPEN_DATASET:
openDataset(i.writable, deref_dynamic_cast< Parameter< O::OPEN_DATASET > >(i.parameter.get()));
break;
case O::DELETE_FILE:
deleteFile(i.writable, deref_dynamic_cast< Parameter< O::DELETE_FILE > >(i.parameter.get()));
break;
case O::DELETE_PATH:
deletePath(i.writable, deref_dynamic_cast< Parameter< O::DELETE_PATH > >(i.parameter.get()));
break;
case O::DELETE_DATASET:
deleteDataset(i.writable, deref_dynamic_cast< Parameter< O::DELETE_DATASET > >(i.parameter.get()));
break;
case O::DELETE_ATT:
deleteAttribute(i.writable, deref_dynamic_cast< Parameter< O::DELETE_ATT > >(i.parameter.get()));
break;
case O::WRITE_DATASET:
writeDataset(i.writable, deref_dynamic_cast< Parameter< O::WRITE_DATASET > >(i.parameter.get()));
break;
case O::WRITE_ATT:
writeAttribute(i.writable, deref_dynamic_cast< Parameter< O::WRITE_ATT > >(i.parameter.get()));
break;
case O::READ_DATASET:
readDataset(i.writable, deref_dynamic_cast< Parameter< O::READ_DATASET > >(i.parameter.get()));
break;
case O::READ_ATT:
readAttribute(i.writable, deref_dynamic_cast< Parameter< O::READ_ATT > >(i.parameter.get()));
break;
case O::LIST_PATHS:
listPaths(i.writable, deref_dynamic_cast< Parameter< O::LIST_PATHS > >(i.parameter.get()));
break;
case O::LIST_DATASETS:
listDatasets(i.writable, deref_dynamic_cast< Parameter< O::LIST_DATASETS > >(i.parameter.get()));
break;
case O::LIST_ATTS:
listAttributes(i.writable, deref_dynamic_cast< Parameter< O::LIST_ATTS > >(i.parameter.get()));
break;
case O::AVAILABLE_CHUNKS:
availableChunks(i.writable, deref_dynamic_cast< Parameter< O::AVAILABLE_CHUNKS > >(i.parameter.get()));
break;
}
} catch (unsupported_data_error&)
{
(*m_handler).m_work.pop();
throw;
}
(*m_handler).m_work.pop();
}
return std::future< void >();
}
/**
* Close the file corresponding with the writable and release file handles.
* The operation should succeed in any access mode.
*/
virtual void
closeFile( Writable *, Parameter< Operation::CLOSE_FILE > const & ) = 0;
/** Report chunks that are available for loading from the dataset represented
* by this writable.
*
* The resulting chunks should be stored into parameters.chunks.
*
*/
virtual void
availableChunks( Writable *, Parameter< Operation::AVAILABLE_CHUNKS > & ) = 0;
/** Create a new file in physical storage, possibly overriding an existing file.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The new file should be located in m_handler->directory.
* The new file should have the filename parameters.name.
* The filename should include the correct corresponding filename extension.
* Any existing file should be overwritten if m_handler->m_frontendAccess is Access::CREATE.
* The Writables file position should correspond to the root group "/" of the hierarchy.
* The Writable should be marked written when the operation completes successfully.
*/
virtual void createFile(Writable*, Parameter< Operation::CREATE_FILE > const&) = 0;
/** Create all necessary groups for a path, possibly recursively.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The path parameters.path may contain multiple levels (e.g. first/second/third/).
* The Writables file position should correspond to the complete newly created path (i.e. first/second/third/ should be assigned to the Writables file position).
* The Writable should be marked written when the operation completes successfully.
*/
virtual void createPath(Writable*, Parameter< Operation::CREATE_PATH > const&) = 0;
/** Create a new dataset of given type, extent and storage properties.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The path may contain multiple levels (e.g. group/dataset).
* The new dataset should have the name parameters.name. This name should not start or end with a slash ("/").
* The new dataset should be of datatype parameters.dtype.
* The new dataset should have an extent of parameters.extent.
* If possible, the new dataset should be extensible.
* If possible, the new dataset should be divided into chunks with size parameters.chunkSize.
* If possible, the new dataset should be compressed according to parameters.compression. This may be format-specific.
* If possible, the new dataset should be transformed accoring to parameters.transform. This may be format-specific.
* The Writables file position should correspond to the newly created dataset.
* The Writable should be marked written when the operation completes successfully.
*/
virtual void createDataset(Writable*, Parameter< Operation::CREATE_DATASET > const&) = 0;
/** Increase the extent of an existing dataset.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The operation should fail if the dataset does not yet exist.
* The dataset should have the name parameters.name. This name should not start or end with a slash ("/").
* The operation should fail if the new extent is not strictly large in every dimension.
* The dataset should have an extent of parameters.extent.
*/
virtual void extendDataset(Writable*, Parameter< Operation::EXTEND_DATASET > const&) = 0;
/** Open an existing file assuming it conforms to openPMD.
*
* The operation should fail if m_handler->directory is not accessible.
* The opened file should have filename parameters.name and include the correct corresponding filename extension.
* The operation should not open files more than once.
* If possible, the file should be opened with read-only permissions if m_handler->m_frontendAccess is Access::READ_ONLY.
* The Writables file position should correspond to the root group "/" of the hierarchy in the opened file.
* The Writable should be marked written when the operation completes successfully.
*/
virtual void openFile(Writable*, Parameter< Operation::OPEN_FILE > const&) = 0;
/** Open all contained groups in a path, possibly recursively.
*
* The operation should overwrite existing file positions, even when the Writable was already marked written.
* The path parameters.path may contain multiple levels (e.g. first/second/third/). This path should be relative (i.e. it should not start with a slash "/").
* The Writables file position should correspond to the complete opened path (i.e. first/second/third/ should be assigned to the Writables file position).
* The Writable should be marked written when the operation completes successfully.
*/
virtual void openPath(Writable*, Parameter< Operation::OPEN_PATH > const&) = 0;
/** Open an existing dataset and determine its datatype and extent.
*
* The opened dataset should be located in a group below the group of the Writables parent writable->parent.
* The opened datasets name should be parameters.name. This name should not start or end with a slash ("/").
* The opened datasets datatype should be stored in *(parameters.dtype).
* The opened datasets extent should be stored in *(parameters.extent).
* The Writables file position should correspond to the opened dataset.
* The Writable should be marked written when the operation completes successfully.
*/
virtual void openDataset(Writable*, Parameter< Operation::OPEN_DATASET > &) = 0;
/** Delete an existing file from physical storage.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The operation should pass if the Writable was not marked written.
* All handles that correspond to the file should be closed before deletion.
* The file to delete should have the filename parameters.name.
* The filename should include the correct corresponding filename extension.
* The Writables file position should be set to an invalid position (i.e. the pointer should be a nullptr).
* The Writable should be marked not written when the operation completes successfully.
*/
virtual void deleteFile(Writable*, Parameter< Operation::DELETE_FILE > const&) = 0;
/** Delete all objects within an existing path.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The operation should pass if the Writable was not marked written.
* The path parameters.path may contain multiple levels (e.g. first/second/third/). This path should be relative (i.e. it should not start with a slash "/"). It may also contain the current group ".".
* All groups and datasets starting from the path should not be accessible in physical storage after the operation completes successfully.
* The Writables file position should be set to an invalid position (i.e. the pointer should be a nullptr).
* The Writable should be marked not written when the operation completes successfully.
*/
virtual void deletePath(Writable*, Parameter< Operation::DELETE_PATH > const&) = 0;
/** Delete an existing dataset.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The operation should pass if the Writable was not marked written.
* The dataset should have the name parameters.name. This name should not start or end with a slash ("/"). It may also contain the current dataset ".".
* The dataset should not be accessible in physical storage after the operation completes successfully.
* The Writables file position should be set to an invalid position (i.e. the pointer should be a nullptr).
* The Writable should be marked not written when the operation completes successfully.
*/
virtual void deleteDataset(Writable*, Parameter< Operation::DELETE_DATASET > const&) = 0;
/** Delete an existing attribute.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The operation should pass if the Writable was not marked written.
* The attribute should be associated with the Writable and have the name parameters.name before deletion.
* The attribute should not be accessible in physical storage after the operation completes successfully.
*/
virtual void deleteAttribute(Writable*, Parameter< Operation::DELETE_ATT > const&) = 0;
/** Write a chunk of data into an existing dataset.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The dataset should be associated with the Writable.
* The operation should fail if the dataset does not exist.
* The operation should fail if the chunk extent parameters.extent is not smaller or equals in every dimension.
* The operation should fail if chunk positions parameters.offset+parameters.extent do not reside inside the dataset.
* The dataset should match the dataype parameters.dtype.
* The data parameters.data is a cast-to-void pointer to a flattened version of the chunk data. It should be re-cast to the provided datatype. The chunk is stored row-major.
* The region of the chunk should be written to physical storage after the operation completes successfully.
*/
virtual void writeDataset(Writable*, Parameter< Operation::WRITE_DATASET > const&) = 0;
/** Create a single attribute and fill the value, possibly overwriting an existing attribute.
*
* The operation should fail if m_handler->m_frontendAccess is Access::READ_ONLY.
* The attribute should have the name parameters.name. This name should not contain a slash ("/").
* The attribute should be of datatype parameters.dtype.
* Any existing attribute with the same name should be overwritten. If possible, only the value should be changed if the datatype stays the same.
* The attribute should be written to physical storage after the operation completes successfully.
* All datatypes of Datatype should be supported in a type-safe way.
*/
virtual void writeAttribute(Writable*, Parameter< Operation::WRITE_ATT > const&) = 0;
/** Read a chunk of data from an existing dataset.
*
* The dataset should be associated with the Writable.
* The operation should fail if the dataset does not exist.
* The operation should fail if the chunk extent parameters.extent is not smaller or equals in every dimension.
* The operation should fail if chunk positions parameters.offset+parameters.extent do not reside inside the dataset.
* The dataset should match the dataype parameters.dtype.
* The data parameters.data should be a cast-to-void pointer to a flattened version of the chunk data. The chunk should be stored row-major.
* The region of the chunk should be written to the location indicated by the pointer after the operation completes successfully.
*/
virtual void readDataset(Writable*, Parameter< Operation::READ_DATASET > &) = 0;
/** Read the value of an existing attribute.
*
* The operation should fail if the Writable was not marked written.
* The operation should fail if the attribute does not exist.
* The attribute should be associated with the Writable and have the name parameters.name. This name should not contain a slash ("/").
* The attribute datatype should be stored in the location indicated by the pointer parameters.dtype.
* The attribute value should be stored as a generic Variant::resource in the location indicated by the pointer parameters.resource.
* All datatypes of Datatype should be supported in a type-safe way.
*/
virtual void readAttribute(Writable*, Parameter< Operation::READ_ATT > &) = 0;
/** List all paths/sub-groups inside a group, non-recursively.
*
* The operation should fail if the Writable was not marked written.
* The operation should fail if the Writable is not a group.
* The list of group names should be stored in the location indicated by the pointer parameters.paths.
*/
virtual void listPaths(Writable*, Parameter< Operation::LIST_PATHS > &) = 0;
/** List all datasets inside a group, non-recursively.
*
* The operation should fail if the Writable was not marked written.
* The operation should fail if the Writable is not a group.
* The list of dataset names should be stored in the location indicated by the pointer parameters.datasets.
*/
virtual void listDatasets(Writable*, Parameter< Operation::LIST_DATASETS > &) = 0;
/** List all attributes associated with an object.
*
* The operation should fail if the Writable was not marked written.
* The attribute should be associated with the Writable.
* The list of attribute names should be stored in the location indicated by the pointer parameters.attributes.
*/
virtual void listAttributes(Writable*, Parameter< Operation::LIST_ATTS > &) = 0;
AbstractIOHandler* m_handler;
}; //AbstractIOHandlerImpl
} // openPMD