1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: file_array.h,v 1.1 2008/08/25 16:20:03 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_FILE_ARRAY_H
22 #define SEQAN_HEADER_FILE_ARRAY_H
28 //////////////////////////////////////////////////////////////////////////////
30 namespace SEQAN_NAMESPACE_MAIN
33 //template < __int64 _FileSize = 2*1024*1024*1024-1, typename TFile = File<> >
36 //template < unsigned _FileCount = 2, typename TFile = File<> >
40 template < __int64 _FileSize, typename TFile >
41 struct Size< File< Chained<_FileSize, TFile> > >
46 template < __int64 _FileSize, typename TFile >
47 struct Position< File< Chained<_FileSize, TFile> > >
52 template < __int64 _FileSize, typename TFile >
53 struct Difference< File< Chained<_FileSize, TFile> > >
58 template < __int64 _FileSize, typename TFile >
59 struct aRequest< File< Chained<_FileSize, TFile> > >
61 typedef typename aRequest<TFile>::Type Type;
65 template < unsigned _FileCount, typename TFile >
66 struct Size< File< Striped<_FileCount, TFile> > >
71 template < unsigned _FileCount, typename TFile >
72 struct Position< File< Striped<_FileCount, TFile> > >
77 template < unsigned _FileCount, typename TFile >
78 struct Difference< File< Striped<_FileCount, TFile> > >
83 template < unsigned _FileCount, typename TFile >
84 struct aRequest< File< Striped<_FileCount, TFile> > >
86 typedef typename aRequest<TFile>::Type Type;
90 template < unsigned _FileCount, typename TFile >
91 class File< Striped<_FileCount, TFile> >: public Tuple< TFile, _FileCount > {
92 File(void *dummy = NULL) {} // to be compatible with the FILE*(NULL) constructor
93 operator bool() const { return (*this)[0]; }
96 template < __int64 _FileSize, typename TFile >
97 class File< Chained<_FileSize, TFile> >: public String< TFile > {
98 typedef String< TFile > Base;
100 ::std::string baseName;
105 File(void *dummy = NULL) : // to be compatible with the FILE*(NULL) constructor
113 template < typename TSize, typename TValue >
114 inline void _alignFloor(TSize _size, TValue const *) {
115 __int64 alignment = sizeof(TValue) * sectorSize(TFile());
116 fileSize = (_size / alignment) * alignment;
119 template < typename TSize, typename TValue >
120 inline void _alignCeil(TSize _size, TValue const *) {
121 __int64 alignment = sizeof(TValue) * sectorSize(TFile());
122 fileSize = ((_size + alignment - 1) / alignment) * alignment;
127 inline ::std::string getFileName(int i) const {
128 ::std::stringstream strm;
129 strm << baseName << '.' << ::std::setfill('0') << ::std::setw(3) << i;
133 inline operator bool() const {
137 inline unsigned fileCount() const {
138 return length(*(Base*)this);
141 inline TFile& getFile(int fileNo) {
142 unsigned _oldFileCount = fileCount();
143 if (fileNo >= _oldFileCount) {
144 resize(*(Base*)this, fileNo + 1);
145 for(unsigned i = _oldFileCount; i <= fileNo; ++i)
147 openTemp((*this)[i], openMode);
149 open((*this)[i], getFileName(i).c_str(), openMode);
151 return (*this)[fileNo];
154 inline void tryOpen() {
155 unsigned fileCount = 0;
156 while (fileExists(getFileName(fileCount).c_str())) ++fileCount;
158 fileSize = size(getFile(0));
159 _realign = (fileCount == 1);
160 getFile(fileCount - 1);
164 // fileSize dependent functions
166 template < typename TValue >
167 inline void adjustFileSize(TValue const *dummy) {
169 _alignCeil(fileSize, dummy);
171 if (fileSize < _FileSize)
175 _alignFloor(_FileSize, dummy);
178 template < typename TPos, typename TOffset, typename TValue >
179 inline TFile& getFileAndOffset(TPos offset, TOffset &fileOffset, TValue const *dummy) {
180 adjustFileSize(dummy);
181 offset *= sizeof(TValue);
182 fileOffset = (offset % fileSize) / sizeof(TValue);
183 return getFile(offset / fileSize);
186 template < typename TOffset, typename TValue >
187 inline __int64 restAt(TOffset fileOffset, TValue const *dummy) {
188 adjustFileSize(dummy);
189 __int64 restBytes = fileSize;
190 restBytes -= fileOffset * sizeof(TValue);
191 return restBytes / sizeof(TValue);
194 inline void resizeArray(__int64 _newSize) {
196 unsigned _oldFileCount = fileCount();
197 unsigned _newFileCount = enclosingBlocks(_newSize, fileSize);
198 for(unsigned i = _newFileCount; i < _oldFileCount; ++i) {
200 if (!temporary) fileUnlink(getFileName(i).c_str());
202 resize(*(Base*)this, _newFileCount);
204 typename Size<TFile>::Type lastFileSize = _newSize % fileSize;
205 if (fileSize) resize((*this)[_newFileCount - 1], lastFileSize);
210 inline void clearInternals() {
218 //////////////////////////////////////////////////////////////////////////////
219 // generic open/close interface
220 template < typename TFileArray >
221 inline bool _openTempFArray(TFileArray &me, int openMode) {
223 for(int i = 0; i < length(me); ++i)
224 result &= openTemp(me[i], openMode);
228 template < typename TFileArray >
229 inline bool _openTempFArray(TFileArray &me) {
230 return _openTempFArray(me, DefaultOpenTempMode<TFileArray>::VALUE);
233 template < typename TFileArray >
234 inline bool _reopenFArray(TFileArray &me, int openMode) {
236 for(int i = 0; i < length(me); ++i)
237 result &= reopen(me[i], openMode);
241 template < typename TFileArray >
242 inline bool _closeFArray(TFileArray &me) {
244 for(int i = 0; i < length(me); ++i)
245 if (me[i]) result &= close(me[i]);
249 template < typename TFileArray >
250 inline unsigned _sectorSizeFArray(TFileArray &me, int openMode) {
251 return sectorSize(me[0]);
254 template < typename TFileArray >
255 inline typename Size<TFileArray>::Type
256 _sizeFArray(TFileArray &me) {
257 typename Size<TFileArray>::Type sum = 0;
258 for(int i = 0; i < length(me); ++i)
263 template < typename TFileArray >
264 inline bool _flushFArray(TFileArray &me) {
266 for(int i = 0; i < length(me); ++i)
267 result &= flush(me[i]);
271 template < typename TFileArray, typename TRequest >
272 inline bool _cancelFArray(TFileArray &me, TRequest &request) {
274 for(int i = 0; i < length(me); ++i)
275 result &= cancel(me[i], &request);
280 //////////////////////////////////////////////////////////////////////////////
281 // standard file array wrappers
283 template < __int64 _FileSize, typename TFile >
284 inline unsigned length(File< Chained<_FileSize, TFile> > const &me) {
285 return me.fileCount();
288 template < unsigned _FileCount, typename TFile >
289 inline unsigned length(File< Striped<_FileCount, TFile> > const &me) {
293 template < __int64 _FileSize, typename TFile >
294 inline bool open(File< Chained<_FileSize, TFile> > &me, const char *fileName, int openMode) {
295 me.baseName = fileName;
296 me.openMode = openMode;
297 me.temporary = false;
302 template < __int64 _FileSize, typename TFile >
303 inline bool openTemp(File< Chained<_FileSize, TFile> > &me, int openMode) {
304 me.openMode = openMode;
309 template < unsigned _FileCount, typename TFile >
310 inline bool openTemp(File< Striped<_FileCount, TFile> > &me, int openMode) {
311 return _openTempFArray(me, openMode);
314 template < __int64 _FileSize, typename TFile >
315 inline bool close(File< Chained<_FileSize, TFile> > &me) {
321 template < unsigned _FileCount, typename TFile >
322 inline bool close(File< Striped<_FileCount, TFile> > &me) { return _closeFArray(me); }
324 template < __int64 _FileSize, typename TFile >
325 __int64 size(File< Chained<_FileSize, TFile> > &me) {
326 return _sizeFArray(me);
329 template < unsigned _FileCount, typename TFile >
330 __int64 size(File< Striped<_FileCount, TFile> > &me) {
331 return _sizeFArray(me);
334 template < __int64 _FileSize, typename TFile, typename TSize >
335 inline void resize(File< Chained<_FileSize, TFile> > &me, TSize new_length) {
336 me.resizeArray(new_length);
339 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize >
340 inline void allocate(File< Chained<_FileSize, TFile> > const &me, TValue* &data, TSize count) {
341 allocate(me[0], data, count);
344 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize >
345 inline void deallocate(File< Chained<_FileSize, TFile> > const &me, TValue* &data, TSize count) {
346 deallocate(me[0], data, count);
349 template < unsigned _FileCount, typename TFile, typename TValue, typename TSize >
350 inline void allocate(File< Striped<_FileCount, TFile> > const &me, TValue* &data, TSize count) {
351 allocate(me[0], data, count);
354 template < unsigned _FileCount, typename TFile, typename TValue, typename TSize >
355 inline void deallocate(File< Striped<_FileCount, TFile> > const &me, TValue* &data, TSize count) {
356 deallocate(me[0], data, count);
360 //////////////////////////////////////////////////////////////////////////////
361 // read/write wrappers
363 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize, typename TOffset >
364 inline bool readAt(File< Chained<_FileSize, TFile> > &me, TValue *memPtr, TSize count, TOffset offset) {
367 TFile &file = me.getFileAndOffset(offset, fileOfs, memPtr);
368 TSize xmitSize = _min(me.restAt(fileOfs, memPtr), (__int64)count);
369 if (!readAt(file, memPtr, xmitSize, fileOfs)) return false;
377 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize, typename TOffset >
378 inline bool writeAt(File< Chained<_FileSize, TFile> > &me, TValue const *memPtr, TSize count, TOffset offset) {
381 TFile &file = me.getFileAndOffset(offset, fileOfs, memPtr);
382 TSize xmitSize = _min(me.restAt(fileOfs, memPtr), (__int64)count);
383 if (!writeAt(file, memPtr, xmitSize, fileOfs)) return false;
391 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize, typename TOffset, typename TRequest >
392 inline bool areadAt(File< Chained<_FileSize, TFile> > &me, TValue *memPtr, TSize count, TOffset offset, TRequest &req) {
395 TFile &file = me.getFileAndOffset(offset, fileOfs, memPtr);
396 TSize xmitSize = _min(me.restAt(fileOfs, memPtr), (__int64)count);
397 if (count != xmitSize) {
398 if (!readAt(file, memPtr, xmitSize, fileOfs)) return false;
400 if (!areadAt(file, memPtr, xmitSize, fileOfs, req)) return false;
408 template < __int64 _FileSize, typename TFile, typename TValue, typename TSize, typename TOffset, typename TRequest >
409 inline bool awriteAt(File< Chained<_FileSize, TFile> > &me, TValue const *memPtr, TSize count, TOffset offset, TRequest &req) {
412 TFile &file = me.getFileAndOffset(offset, fileOfs, memPtr);
413 TSize xmitSize = _min(me.restAt(fileOfs, memPtr), (__int64)count);
414 if (count != xmitSize) {
415 if (!writeAt(file, memPtr, xmitSize, fileOfs)) return false;
417 if (!awriteAt(file, memPtr, xmitSize, fileOfs, req)) return false;