casacore
Loading...
Searching...
No Matches
MultiFileBase.h
Go to the documentation of this file.
1// # MultiFileBase.h: Abstract base class to combine multiple files in a single one
2// # Copyright (C) 2014
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_MULTIFILEBASE_H
27#define CASA_MULTIFILEBASE_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/casa/IO/ByteIO.h>
32#include <casacore/casa/BasicSL/String.h>
33#include <casacore/casa/ostream.h>
34#include <vector>
35#include <memory>
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// # Forward declaration.
40class AipsIO;
41class HDF5Group;
42class HDF5DataSet;
43
44// <summary>
45// Helper class for MultiFileInfo holding a data buffer
46// </summary>
47// <synopsis>
48// The buffer can be allocated with posix_memalign (for O_DIRECT support).
49// Hence the memory must be freed using free, which makes it impossible
50// to use a shared_ptr to that memory. Hence it is encapsulated in this class.
51// </synopsis>
53 public:
54 MultiFileBuffer(size_t bufSize, Bool useODirect);
58 // Forbid copy constructor.
60 // Forbid assignment.
62 char* data() { return itsData; }
63
64 private:
65 // Data members
66 char* itsData;
67};
68
69// <summary>
70// Helper class for MultiFileBase containing info per logical file.
71// </summary>
72// <synopsis>
73// This struct defines the basic fields describing a logical file in a
74// class derived from MultiFileBase (such as MultiFile or MultiHDF5).
75// </synopsis>
76// <use visibility=local>
78 // Initialize the object. The buffer is created when the file is opened.
79 explicit MultiFileInfo();
80 // Allocate the buffer.
81 void allocBuffer(size_t bufSize, Bool useODirect) {
82 buffer = std::make_shared<MultiFileBuffer>(bufSize, useODirect);
83 }
84 // # Data members.
85 std::vector<Int64> blockNrs; // physical blocknrs for this logical file
86 Int64 curBlock; // the data block held in buffer (<0 is none)
87 Int64 fsize; // file size (in bytes)
88 String name; // the virtual file name
89 Bool nested; // is the file a nested MultiFile?
90 Bool dirty; // has data in buffer been changed?
91 std::shared_ptr<MultiFileBuffer> buffer; // buffer holding a data block
92 std::shared_ptr<HDF5Group> group;
93 std::shared_ptr<HDF5DataSet> dataSet;
94};
95ostream& operator<<(ostream&, const MultiFileInfo&);
98void getInfoVersion1(AipsIO&, std::vector<MultiFileInfo>&);
99
100// <summary>
101// Abstract base class to combine multiple logical files in a single one.
102// </summary>
103
104// <use visibility=export>
105
106// <reviewed reviewer="" date="" tests="tMultiFile" demos="">
107// </reviewed>
108
109// <synopsis>
110// This class is the abstract base class for classes defining a container
111// file holding multiple logical files. These classes are meant as a
112// container files for the storage manager files of a table to reduce the
113// number of files used (especially for Lustre) and to reduce the number
114// of open files (especially when concatenating tables).
115// The derived classes MultiFile and MultiHDF5 implement such container
116// files using a regular file and HDF5, resp.
117//
118// MultiFileBase implements several functions with common functionality
119// for the derived classes.
120//
121// A logical file is represented by an MFFileIO object, which is derived
122// from ByteIO and as such part of the casacore IO framework. It makes it
123// possible for applications to access a logical file in the same way as
124// a regular file.
125// </synopsis>
126
128 public:
129 // Create a MultiFileBase object with the given name.
130 // <br>Upon creation of the container file the block size can be given.
131 // If <=0, it uses the block size of the file system the file is on,
132 // but it will not be less than the absolute value of the given block size.
133 // <br>If useODIrect=True, it means that O_DIRECT is used. If the OS does not
134 // support it (as determined at configure time), the flag will always be
135 // set to False. If True, the data buffers will have a proper alignment
136 // and size (as needed by O_DIRECT).
138
139 // The destructor flushes dirty blocks and closes the container file.
140 virtual ~MultiFileBase();
141
142 // Forbid copy constructor.
143 MultiFileBase(const MultiFileBase&) = delete;
144
145 // Forbid assignment.
147
148 // Open the correct MultiFileBase (as plain or HDF5).
149 static std::shared_ptr<MultiFileBase> openMF(const String& fileName);
150
151 // Make the correct MultiFileBase object for a nested file.
152 virtual std::shared_ptr<MultiFileBase> makeNested(const std::shared_ptr<MultiFileBase>& parent,
154 Int blockSize) const = 0;
155
156 // Get the file name of the MultiFileBase container file.
157 String fileName() const { return itsName; }
158
159 // Is the container file writable?
160 Bool isWritable() const { return itsWritable; }
161
162 // Open the given logical file and return its file id.
163 // If the name is unknown, an exception is thrown.
164 // It allocates the internal buffer of the logical file.
166
167 // Create a new logical file and return its file id.
168 // Only the base name of the given file name is used. In this way the
169 // MultiFileBase container file can be moved.
170 // If the logical file already exists, it is deleted if ByteIO::New is
171 // given. Otherwise an exception is thrown.
172 // It allocates the internal buffer of the logical file.
174
175 // Flush the possible dirty buffer of the given logical file.
177
178 // Close a logical file.
179 // It flushes and deallocates its buffer.
181
182 // Delete a logical file. It adds its blocks to the free block list.
184
185 // Get the size of a logical file.
187
188 // Read a block at the given offset in the logical file.
189 // It returns the actual size read.
191
192 // Write a block at the given offset in the logical file.
193 // It returns the actual size written.
194 Int64 write(Int fileId, const void* buffer, Int64 size, Int64 offset);
195
196 // Truncate the logical file to the given size.
198
199 // Reopen the underlying file for read/write access.
200 // Nothing will be done if the file is writable already.
201 // Otherwise it will be reopened and an exception will be thrown
202 // if it is not possible to reopen it for read/write access.
203 virtual void reopenRW() = 0;
204
205 // Flush the file by writing all dirty data and all header info.
206 void flush();
207
208 // Get the block size used.
209 Int64 blockSize() const { return itsBlockSize; }
210
211 // Get the nr of logical files.
212 uInt nfile() const;
213
214 // Get the total nr of data blocks used.
215 Int64 nblock() const { return itsNrBlock; }
216
217 // Get the info object (for test purposes mainly).
218 const std::vector<MultiFileInfo>& info() const { return itsInfo; }
219
220 // Get the free blocks (for test purposes mainly).
221 const std::vector<Int64>& freeBlocks() const { return itsFreeBlocks; }
222
223 // Return the file id of a file in the MultiFileBase object.
224 // If the name is unknown, an exception is thrown if throwExcp is set.
225 // Otherwise it returns -1.
226 Int fileId(const String& name, Bool throwExcp = True) const;
227
228 // Is O_DIRECT used?
229 Bool useODirect() const { return itsUseODirect; }
230
231 protected:
232 // Resync with another process by clearing the buffers and rereading
233 // the header. The header is only read if its counter has changed.
234 void resync();
235
236 // Fsync the file (i.e., force the data to be physically written).
237 virtual void fsync() = 0;
238
239 private:
240 // Write the dirty block and clear dirty flag.
242 writeBlock(info, info.curBlock, info.buffer->data());
243 info.dirty = False;
244 }
245
246 // Add a file to the MultiFileBase object. It returns the file id.
247 // Only the base name of the given file name is used. In this way the
248 // MultiFileBase container file can be moved.
250
251 // Do the class-specific actions on opening a logical file.
252 virtual void doOpenFile(MultiFileInfo&) = 0;
253 // Do the class-specific actions on closing a logical file.
254 virtual void doCloseFile(MultiFileInfo&) = 0;
255 // Do the class-specific actions on adding a logical file.
256 virtual void doAddFile(MultiFileInfo&) = 0;
257 // Do the class-specific actions on deleting a logical file.
258 virtual void doDeleteFile(MultiFileInfo&) = 0;
259 // Truncate the container file to <src>nrblk</src> blocks.
260 virtual void doTruncateFile(MultiFileInfo& info, uInt64 nrblk) = 0;
261 // Flush the container file.
262 virtual void doFlushFile() = 0;
263 // Flush and close the container file.
264 virtual void close() = 0;
265 // Write the header info.
266 virtual void writeHeader() = 0;
267 // Read the header info. If always==False, the info is only read if the
268 // header counter has changed.
269 virtual void readHeader(Bool always = True) = 0;
270 // Extend a logical file to fit lastblk.
271 virtual void extend(MultiFileInfo& info, Int64 lastblk) = 0;
272 // Write a data block of a logical file into the container file.
273 virtual void writeBlock(MultiFileInfo& info, Int64 blknr, const void* buffer) = 0;
274 // Read a data block of a logical file from the container file.
275 virtual void readBlock(MultiFileInfo& info, Int64 blknr, void* buffer) = 0;
276
277 protected:
278 // Set the flags and blockSize for a new MultiFile/HDF5.
280
281 // # Data members
283 Int64 itsBlockSize; // The blocksize used
284 Int64 itsNrBlock; // The total nr of blocks actually used
285 Int64 itsHdrCounter; // Counter of header changes
286 std::vector<MultiFileInfo> itsInfo;
287 std::shared_ptr<MultiFileBuffer> itsBuffer;
288 Bool itsUseODirect; // use O_DIRECT?
289 Bool itsWritable; // Is the file writable?
290 Bool itsChanged; // Has header info changed since last flush?
291 std::vector<Int64> itsFreeBlocks;
292};
293
294} // namespace casacore
295
296#endif
OpenOption
Define the possible ByteIO open options.
Definition ByteIO.h:60
@ New
read/write; create file if not exist.
Definition ByteIO.h:67
void flushFile(Int fileId)
Flush the possible dirty buffer of the given logical file.
virtual void doCloseFile(MultiFileInfo &)=0
Do the class-specific actions on closing a logical file.
Int64 nblock() const
Get the total nr of data blocks used.
Int64 blockSize() const
Get the block size used.
static std::shared_ptr< MultiFileBase > openMF(const String &fileName)
Open the correct MultiFileBase (as plain or HDF5).
MultiFileBase & operator=(const MultiFileBase &)=delete
Forbid assignment.
virtual void extend(MultiFileInfo &info, Int64 lastblk)=0
Extend a logical file to fit lastblk.
virtual void doFlushFile()=0
Flush the container file.
virtual void writeHeader()=0
Write the header info.
std::vector< Int64 > itsFreeBlocks
MultiFileBase(const String &name, Int blockSize, Bool useODirect)
Create a MultiFileBase object with the given name.
MultiFileBase(const MultiFileBase &)=delete
Forbid copy constructor.
virtual void fsync()=0
Fsync the file (i.e., force the data to be physically written).
virtual void readHeader(Bool always=True)=0
Read the header info.
Int64 write(Int fileId, const void *buffer, Int64 size, Int64 offset)
Write a block at the given offset in the logical file.
void resync()
Resync with another process by clearing the buffers and rereading the header.
virtual std::shared_ptr< MultiFileBase > makeNested(const std::shared_ptr< MultiFileBase > &parent, const String &name, ByteIO::OpenOption, Int blockSize) const =0
Make the correct MultiFileBase object for a nested file.
Int createFile(const String &name, ByteIO::OpenOption=ByteIO::New)
Create a new logical file and return its file id.
Int addFile(const String &name)
Add a file to the MultiFileBase object.
Int openFile(const String &name)
Open the given logical file and return its file id.
Int fileId(const String &name, Bool throwExcp=True) const
Return the file id of a file in the MultiFileBase object.
virtual void doTruncateFile(MultiFileInfo &info, uInt64 nrblk)=0
Truncate the container file to nrblk blocks.
const std::vector< MultiFileInfo > & info() const
Get the info object (for test purposes mainly).
const std::vector< Int64 > & freeBlocks() const
Get the free blocks (for test purposes mainly).
Int64 fileSize(Int fileId) const
Get the size of a logical file.
void deleteFile(Int fileId)
Delete a logical file.
virtual void doOpenFile(MultiFileInfo &)=0
Do the class-specific actions on opening a logical file.
Int64 read(Int fileId, void *buffer, Int64 size, Int64 offset)
Read a block at the given offset in the logical file.
String fileName() const
Get the file name of the MultiFileBase container file.
Bool useODirect() const
Is O_DIRECT used?
void truncate(Int fileId, Int64 size)
Truncate the logical file to the given size.
virtual ~MultiFileBase()
The destructor flushes dirty blocks and closes the container file.
Bool isWritable() const
Is the container file writable?
virtual void doDeleteFile(MultiFileInfo &)=0
Do the class-specific actions on deleting a logical file.
virtual void writeBlock(MultiFileInfo &info, Int64 blknr, const void *buffer)=0
Write a data block of a logical file into the container file.
virtual void reopenRW()=0
Reopen the underlying file for read/write access.
std::vector< MultiFileInfo > itsInfo
virtual void readBlock(MultiFileInfo &info, Int64 blknr, void *buffer)=0
Read a data block of a logical file from the container file.
virtual void close()=0
Flush and close the container file.
void setNewFile()
Set the flags and blockSize for a new MultiFile/HDF5.
virtual void doAddFile(MultiFileInfo &)=0
Do the class-specific actions on adding a logical file.
void flush()
Flush the file by writing all dirty data and all header info.
uInt nfile() const
Get the nr of logical files.
void closeFile(Int fileId)
Close a logical file.
std::shared_ptr< MultiFileBuffer > itsBuffer
void writeDirty(MultiFileInfo &info)
Write the dirty block and clear dirty flag.
char * itsData
Data members.
MultiFileBuffer(size_t bufSize, Bool useODirect)
MultiFileBuffer(const MultiFileBuffer &)=delete
Forbid copy constructor.
MultiFileBuffer & operator=(const MultiFileBuffer &)=delete
Forbid assignment.
String: the storage and methods of handling collections of characters.
Definition String.h:355
free(pool)
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
friend AipsIO & operator>>(AipsIO &os, Record &rec)
Read the Record from an input stream.
Definition Record.h:431
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
int offset(int, int) const
compute a linear offset from array indicies
unsigned int uInt
Definition aipstype.h:49
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size).
Definition aipsxtype.h:36
String name() const
Return the name of the field.
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
size_t size() const
Definition Block.h:566
void getInfoVersion1(AipsIO &, std::vector< MultiFileInfo > &)
const Bool True
Definition aipstype.h:41
unsigned long long uInt64
Definition aipsxtype.h:37
Helper class for MultiFileBase containing info per logical file.
void allocBuffer(size_t bufSize, Bool useODirect)
Allocate the buffer.
std::shared_ptr< MultiFileBuffer > buffer
std::vector< Int64 > blockNrs
std::shared_ptr< HDF5Group > group
MultiFileInfo()
Initialize the object.
std::shared_ptr< HDF5DataSet > dataSet