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.
40 class AipsIO;
41 class HDF5Group;
42 class HDF5DataSet;
43
44
45 // <summary>
46 // Helper class for MultiFileInfo holding a data buffer
47 // </summary>
48 // <synopsis>
49 // The buffer can be allocated with posix_memalign (for O_DIRECT support).
50 // Hence the memory must be freed using free, which makes it impossible
51 // to use a shared_ptr to that memory. Hence it is encapsulated in this class.
52 // </synopsis>
54 public:
55 MultiFileBuffer (size_t bufSize, Bool useODirect);
58 // Forbid copy constructor.
60 // Forbid assignment.
62 char* data()
63 { return itsData; }
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 //# Data members.
84 std::vector<Int64> blockNrs; // physical blocknrs for this logical file
85 Int64 curBlock; // the data block held in buffer (<0 is none)
86 Int64 fsize; // file size (in bytes)
87 String name; // the virtual file name
88 Bool nested; // is the file a nested MultiFile?
89 Bool dirty; // has data in buffer been changed?
90 std::shared_ptr<MultiFileBuffer> buffer; // buffer holding a data block
91 std::shared_ptr<HDF5Group> group;
92 std::shared_ptr<HDF5DataSet> dataSet;
93 };
94 ostream& operator<< (ostream&, const MultiFileInfo&);
97 void getInfoVersion1 (AipsIO&, std::vector<MultiFileInfo>&);
98
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 {
129 public:
130 // Create a MultiFileBase object with the given name.
131 // <br>Upon creation of the container file the block size can be given.
132 // If <=0, it uses the block size of the file system the file is on,
133 // but it will not be less than the absolute value of the given block size.
134 // <br>If useODIrect=True, it means that O_DIRECT is used. If the OS does not
135 // support it (as determined at configure time), the flag will always be
136 // set to False. If True, the data buffers will have a proper alignment
137 // and size (as needed by O_DIRECT).
139
140 // The destructor flushes dirty blocks and closes the container file.
141 virtual ~MultiFileBase();
142
143 // Forbid copy constructor.
144 MultiFileBase (const MultiFileBase&) = delete;
145
146 // Forbid assignment.
148
149 // Open the correct MultiFileBase (as plain or HDF5).
150 static std::shared_ptr<MultiFileBase> openMF (const String& fileName);
151
152 // Make the correct MultiFileBase object for a nested file.
153 virtual std::shared_ptr<MultiFileBase> makeNested
154 (const std::shared_ptr<MultiFileBase>& parent, const String& name,
155 ByteIO::OpenOption, Int blockSize) const = 0;
156
157 // Get the file name of the MultiFileBase container file.
159 { return itsName; }
160
161 // Is the container file writable?
163 { return itsWritable; }
164
165 // Open the given logical file and return its file id.
166 // If the name is unknown, an exception is thrown.
167 // It allocates the internal buffer of the logical file.
168 Int openFile (const String& name);
169
170 // Create a new logical file and return its file id.
171 // Only the base name of the given file name is used. In this way the
172 // MultiFileBase container file can be moved.
173 // If the logical file already exists, it is deleted if ByteIO::New is
174 // given. Otherwise an exception is thrown.
175 // It allocates the internal buffer of the logical file.
177
178 // Flush the possible dirty buffer of the given logical file.
180
181 // Close a logical file.
182 // It flushes and deallocates its buffer.
184
185 // Delete a logical file. It adds its blocks to the free block list.
187
188 // Get the size of a logical file.
190
191 // Read a block at the given offset in the logical file.
192 // It returns the actual size read.
193 Int64 read (Int fileId, void* buffer, Int64 size, Int64 offset);
194
195 // Write a block at the given offset in the logical file.
196 // It returns the actual size written.
197 Int64 write (Int fileId, const void* buffer, Int64 size, Int64 offset);
198
199 // Truncate the logical file to the given size.
200 void truncate (Int fileId, Int64 size);
201
202 // Reopen the underlying file for read/write access.
203 // Nothing will be done if the file is writable already.
204 // Otherwise it will be reopened and an exception will be thrown
205 // if it is not possible to reopen it for read/write access.
206 virtual void reopenRW() = 0;
207
208 // Flush the file by writing all dirty data and all header info.
209 void flush();
210
211 // Get the block size used.
213 { return itsBlockSize; }
214
215 // Get the nr of logical files.
216 uInt nfile() const;
217
218 // Get the total nr of data blocks used.
219 Int64 nblock() const
220 { return itsNrBlock; }
221
222 // Get the info object (for test purposes mainly).
223 const std::vector<MultiFileInfo>& info() const
224 { return itsInfo; }
225
226 // Get the free blocks (for test purposes mainly).
227 const std::vector<Int64>& freeBlocks() const
228 { return itsFreeBlocks; }
229
230 // Return the file id of a file in the MultiFileBase object.
231 // If the name is unknown, an exception is thrown if throwExcp is set.
232 // Otherwise it returns -1.
233 Int fileId (const String& name, Bool throwExcp=True) const;
234
235 // Is O_DIRECT used?
237 { return itsUseODirect; }
238
239 protected:
240 // Resync with another process by clearing the buffers and rereading
241 // the header. The header is only read if its counter has changed.
242 void resync();
243
244 // Fsync the file (i.e., force the data to be physically written).
245 virtual void fsync() = 0;
246
247 private:
248 // Write the dirty block and clear dirty flag.
250 {
251 writeBlock (info, info.curBlock, info.buffer->data());
252 info.dirty = False;
253 }
254
255 // Add a file to the MultiFileBase object. It returns the file id.
256 // Only the base name of the given file name is used. In this way the
257 // MultiFileBase container file can be moved.
258 Int addFile (const String& name);
259
260 // Do the class-specific actions on opening a logical file.
261 virtual void doOpenFile (MultiFileInfo&) = 0;
262 // Do the class-specific actions on closing a logical file.
263 virtual void doCloseFile (MultiFileInfo&) = 0;
264 // Do the class-specific actions on adding a logical file.
265 virtual void doAddFile (MultiFileInfo&) = 0;
266 // Do the class-specific actions on deleting a logical file.
267 virtual void doDeleteFile (MultiFileInfo&) = 0;
268 // Truncate the container file to <src>nrblk</src> blocks.
269 virtual void doTruncateFile (MultiFileInfo& info, uInt64 nrblk) = 0;
270 // Flush the container file.
271 virtual void doFlushFile() = 0;
272 // Flush and close the container file.
273 virtual void close() = 0;
274 // Write the header info.
275 virtual void writeHeader() = 0;
276 // Read the header info. If always==False, the info is only read if the
277 // header counter has changed.
278 virtual void readHeader (Bool always=True) = 0;
279 // Extend a logical file to fit lastblk.
280 virtual void extend (MultiFileInfo& info, Int64 lastblk) = 0;
281 // Write a data block of a logical file into the container file.
282 virtual void writeBlock (MultiFileInfo& info, Int64 blknr,
283 const void* buffer) = 0;
284 // Read a data block of a logical file from the container file.
285 virtual void readBlock (MultiFileInfo& info, Int64 blknr,
286 void* buffer) = 0;
287
288 protected:
289 // Set the flags and blockSize for a new MultiFile/HDF5.
291
292 //# Data members
294 Int64 itsBlockSize; // The blocksize used
295 Int64 itsNrBlock; // The total nr of blocks actually used
296 Int64 itsHdrCounter; // Counter of header changes
297 std::vector<MultiFileInfo> itsInfo;
298 std::shared_ptr<MultiFileBuffer> itsBuffer;
299 Bool itsUseODirect; // use O_DIRECT?
300 Bool itsWritable; // Is the file writable?
301 Bool itsChanged; // Has header info changed since last flush?
302 std::vector<Int64> itsFreeBlocks;
303 };
304
305
306} //# NAMESPACE CASACORE - END
307
308#endif
OpenOption
Define the possible ByteIO open options.
Definition ByteIO.h:63
@ New
read/write; create file if not exist.
Definition ByteIO.h:70
Abstract base class to combine multiple logical files in a single one.
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:223
free(pool)
this file contains all the compiler specific defines
Definition mainpage.dox:28
const Bool False
Definition aipstype.h:42
AipsIO & operator>>(AipsIO &os, Record &rec)
Definition Record.h:462
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
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
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
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