@@ -125,6 +125,10 @@ bool DataInputDescriptor::setFile(int counter)
125125 }
126126 mcurrentFile->SetReadaheadSize (50 * 1024 * 1024 );
127127
128+ // get the parent file map if exists
129+ mParentFileMap = (TMap*)mcurrentFile->Get (" parent_files" ); // folder name (DF_XXX) --> parent file (absolute path)
130+ // TODO needs configurable to replace part of absolute files if they have been relocated after producing them (e.g. local cluster)
131+
128132 // get the directory names
129133 if (mfilenames[counter]->numberOfTimeFrames <= 0 ) {
130134 std::regex TFRegex = std::regex (" DF_[0-9]+" );
@@ -137,23 +141,29 @@ bool DataInputDescriptor::setFile(int counter)
137141 mfilenames[counter]->listOfTimeFrameNumbers .emplace_back (folderNumber);
138142 }
139143 }
140- std::sort (mfilenames[counter]->listOfTimeFrameNumbers .begin (), mfilenames[counter]->listOfTimeFrameNumbers .end ());
144+ if (mParentFileMap != nullptr ) {
145+ // If we have a parent map, we should not process in DF alphabetical order but according to parent file to avoid swapping between files
146+ std::sort (mfilenames[counter]->listOfTimeFrameNumbers .begin (), mfilenames[counter]->listOfTimeFrameNumbers .end (),
147+ [this ](long const & l1, long const & l2) -> bool {
148+ auto p1 = (TObjString*)this ->mParentFileMap ->GetValue ((" DF_" + std::to_string (l1)).c_str ());
149+ auto p2 = (TObjString*)this ->mParentFileMap ->GetValue ((" DF_" + std::to_string (l2)).c_str ());
150+ return p1->GetString ().CompareTo (p2->GetString ()) < 0 ;
151+ });
152+ } else {
153+ std::sort (mfilenames[counter]->listOfTimeFrameNumbers .begin (), mfilenames[counter]->listOfTimeFrameNumbers .end ());
154+ }
141155
142156 for (auto folderNumber : mfilenames[counter]->listOfTimeFrameNumbers ) {
143157 auto folderName = " DF_" + std::to_string (folderNumber);
144158 mfilenames[counter]->listOfTimeFrameKeys .emplace_back (folderName);
159+ mfilenames[counter]->alreadyRead .emplace_back (false );
145160 }
146161 mfilenames[counter]->numberOfTimeFrames = mfilenames[counter]->listOfTimeFrameKeys .size ();
147162 }
148163
149164 mCurrentFileID = counter;
150- mCurrentFileHighestTFRead = -1 ;
151165 mCurrentFileStartedAt = uv_hrtime ();
152166
153- // get the parent file map if exists
154- mParentFileMap = (TMap*)mcurrentFile->Get (" parent_files" ); // folder name (DF_XXX) --> parent file (absolute path)
155- // TODO needs configurable to replace part of absolute files if they have been relocated after producing them (e.g. local cluster)
156-
157167 return true ;
158168}
159169
@@ -190,7 +200,7 @@ FileAndFolder DataInputDescriptor::getFileFolder(int counter, int numTF)
190200 fileAndFolder.file = mcurrentFile;
191201 fileAndFolder.folderName = (mfilenames[counter]->listOfTimeFrameKeys )[numTF];
192202
193- mCurrentFileHighestTFRead = numTF ;
203+ mfilenames[counter]-> alreadyRead [numTF] = true ;
194204
195205 return fileAndFolder;
196206}
@@ -212,7 +222,6 @@ DataInputDescriptor* DataInputDescriptor::getParentFile(int counter, int numTF)
212222 if (mParentFile ) {
213223 // Is this still the corresponding to the correct file?
214224 if (parentFileName->GetString ().CompareTo (mParentFile ->mcurrentFile ->GetName ()) == 0 ) {
215- mParentFile ->mCurrentFileHighestTFRead = numTF;
216225 return mParentFile ;
217226 } else {
218227 mParentFile ->closeInputFile ();
@@ -221,13 +230,12 @@ DataInputDescriptor* DataInputDescriptor::getParentFile(int counter, int numTF)
221230 }
222231 }
223232
224- LOGP (info, " Opening parent file {}" , parentFileName->GetString ().Data ());
233+ LOGP (info, " Opening parent file {} for DF {} " , parentFileName->GetString ().Data (), folderName. c_str ());
225234 mParentFile = new DataInputDescriptor (mAlienSupport , mLevel + 1 , mMonitoring );
226235 mParentFile ->mdefaultFilenamesPtr = new std::vector<FileNameHolder*>;
227236 mParentFile ->mdefaultFilenamesPtr ->emplace_back (makeFileNameHolder (parentFileName->GetString ().Data ()));
228237 mParentFile ->fillInputfiles ();
229238 mParentFile ->setFile (0 );
230- mParentFile ->mCurrentFileHighestTFRead = numTF;
231239 return mParentFile ;
232240}
233241
@@ -236,14 +244,20 @@ int DataInputDescriptor::getTimeFramesInFile(int counter)
236244 return mfilenames.at (counter)->numberOfTimeFrames ;
237245}
238246
247+ int DataInputDescriptor::getReadTimeFramesInFile (int counter)
248+ {
249+ auto & list = mfilenames.at (counter)->alreadyRead ;
250+ return std::count (list.begin (), list.end (), true );
251+ }
252+
239253void DataInputDescriptor::printFileStatistics ()
240254{
241255 uint64_t wait_time = 0 ;
242256 if (uv_hrtime () > mCurrentFileStartedAt - mIOTime ) {
243257 wait_time = uv_hrtime () - mCurrentFileStartedAt - mIOTime ;
244258 }
245259 std::string monitoringInfo (fmt::format (" lfn={},size={},total_df={},read_df={},read_bytes={},read_calls={},io_time={:.1f},wait_time={:.1f},level={}" , mcurrentFile->GetName (),
246- mcurrentFile->GetSize (), getTimeFramesInFile (mCurrentFileID ), mCurrentFileHighestTFRead + 1 , mcurrentFile->GetBytesRead (), mcurrentFile->GetReadCalls (),
260+ mcurrentFile->GetSize (), getTimeFramesInFile (mCurrentFileID ), getReadTimeFramesInFile ( mCurrentFileID ) , mcurrentFile->GetBytesRead (), mcurrentFile->GetReadCalls (),
247261 ((float )mIOTime / 1e9 ), ((float )wait_time / 1e9 ), mLevel ));
248262#if __has_include(<TJAlienFile.h>)
249263 auto alienFile = dynamic_cast <TJAlienFile*>(mcurrentFile);
@@ -316,6 +330,16 @@ int DataInputDescriptor::fillInputfiles()
316330 return getNumberInputfiles ();
317331}
318332
333+ int DataInputDescriptor::findDFNumber (int file, std::string dfName)
334+ {
335+ auto dfList = mfilenames[file]->listOfTimeFrameKeys ;
336+ auto it = std::find (dfList.begin (), dfList.end (), dfName);
337+ if (it == dfList.end ()) {
338+ return -1 ;
339+ }
340+ return it - dfList.begin ();
341+ }
342+
319343bool DataInputDescriptor::readTree (DataAllocator& outputs, header::DataHeader dh, int counter, int numTF, std::string treename, size_t & totalSizeCompressed, size_t & totalSizeUncompressed)
320344{
321345 auto ioStart = uv_hrtime ();
@@ -332,8 +356,12 @@ bool DataInputDescriptor::readTree(DataAllocator& outputs, header::DataHeader dh
332356 LOGP (debug, " Could not find tree {}. Trying in parent file." , fullpath.c_str ());
333357 auto parentFile = getParentFile (counter, numTF);
334358 if (parentFile != nullptr ) {
359+ int parentNumTF = parentFile->findDFNumber (0 , fileAndFolder.folderName );
360+ if (parentNumTF == -1 ) {
361+ throw std::runtime_error (fmt::format (R"( DF {} listed in parent file map but not found in the corresponding file "{}")" , fileAndFolder.folderName , parentFile->mcurrentFile ->GetName ()));
362+ }
335363 // first argument is 0 as the parent file object contains only 1 file
336- return parentFile->readTree (outputs, dh, 0 , numTF , treename, totalSizeCompressed, totalSizeUncompressed);
364+ return parentFile->readTree (outputs, dh, 0 , parentNumTF , treename, totalSizeCompressed, totalSizeUncompressed);
337365 }
338366 throw std::runtime_error (fmt::format (R"( Couldn't get TTree "{}" from "{}". Please check https://aliceo2group.github.io/analysis-framework/docs/troubleshooting/treenotfound.html for more information.)" , fileAndFolder.folderName + " /" + treename, fileAndFolder.file ->GetName ()));
339367 }
0 commit comments