@@ -252,100 +252,98 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const
252252 *fileCounter = (fcnt - device.inputTimesliceId ) / device.maxInputTimeslices ;
253253 *numTF = ntf;
254254 };
255- enum class ReadState {
256- BEFORE_FIRST_READ ,
257- FIRST_READ ,
258- READ ,
259- NOT_READ_AND_FIRST ,
260- NOT_READ_AND_MIDDLE ,
255+ enum class TFReaderState {
256+ READ_TIMEFRAME ,
257+ TRY_NEXT_FILE ,
258+ TIMEFRAME_READ ,
259+ INVALID_TIMEFRAME ,
260+ END_OF_INPUT ,
261261 };
262- auto readState = ReadState::BEFORE_FIRST_READ ;
263- for (auto & route : requestedTables) {
264- if ((device.inputTimesliceId % route.maxTimeslices ) != route.timeslice ) {
265- continue ;
262+ auto readState = TFReaderState::READ_TIMEFRAME ;
263+ bool triedNextFile = false ;
264+ while (readState == TFReaderState::READ_TIMEFRAME || readState == TFReaderState::TRY_NEXT_FILE ) {
265+ if (readState == TFReaderState::TRY_NEXT_FILE ) {
266+ fcnt += device.maxInputTimeslices ;
267+ if (didir->atEnd (fcnt)) {
268+ readState = TFReaderState::END_OF_INPUT ;
269+ break ;
270+ }
271+ ntf = 0 ;
272+ triedNextFile = true ;
266273 }
267274
268- // create header
269- auto concrete = DataSpecUtils::asConcreteDataMatcher (route.matcher );
270- auto dh = header::DataHeader (concrete.description , concrete.origin , concrete.subSpec );
271- bool wasAOD = std::ranges::any_of (route.matcher .metadata , [](ConfigParamSpec const & p) { return p.name .starts_with (" aod-origin-replaced" ); });
272-
273- try {
274- if (didir->readTree (outputs, dh, fcnt, ntf, totalSizeCompressed, totalSizeUncompressed, wasAOD)) {
275- readState = readState == ReadState::BEFORE_FIRST_READ ? ReadState::FIRST_READ : ReadState::READ ;
276- } else {
277- readState = readState == ReadState::BEFORE_FIRST_READ ? ReadState::NOT_READ_AND_FIRST : ReadState::NOT_READ_AND_MIDDLE ;
278- }
279- } catch (InvalidAODReadError const & e) {
280- if (!skipInvalidReads) {
281- throw ;
275+ readState = TFReaderState::TIMEFRAME_READ ;
276+ bool firstTable = true ;
277+ for (auto & route : requestedTables) {
278+ if ((device.inputTimesliceId % route.maxTimeslices ) != route.timeslice ) {
279+ continue ;
282280 }
283- skipInvalidRead (concrete.origin , e);
284- return ;
285- }
286281
287- switch (readState) {
288- case ReadState::FIRST_READ :
289- case ReadState::READ :
290- break ;
291- case ReadState::NOT_READ_AND_MIDDLE :
292- LOGP (fatal, " Can not retrieve tree for table {}: fileCounter {}, timeFrame {}" , concrete.origin .as <std::string>(), fcnt, ntf);
293- throw std::runtime_error (" Processing is stopped!" );
294- case ReadState::NOT_READ_AND_FIRST :
295- // check if there is a next file to read
296- fcnt += device.maxInputTimeslices ;
297- if (didir->atEnd (fcnt)) {
298- LOGP (info, " No input files left to read for reader {}!" , device.inputTimesliceId );
299- didir->closeInputFiles ();
300- monitoring.flushBuffer ();
301- control.endOfStream ();
302- control.readyToQuit (QuitRequest::Me);
303- return ;
304- }
305- // get first folder of next file
306- ntf = 0 ;
307- try {
308- if (!didir->readTree (outputs, dh, fcnt, ntf, totalSizeCompressed, totalSizeUncompressed, wasAOD)) {
309- LOGP (fatal, " Can not retrieve tree for table {}: fileCounter {}, timeFrame {}" , concrete.origin .as <std::string>(), fcnt, ntf);
310- throw std::runtime_error (" Processing is stopped!" );
311- }
312- } catch (InvalidAODReadError const & e) {
313- if (!skipInvalidReads) {
314- throw ;
282+ // create header
283+ auto concrete = DataSpecUtils::asConcreteDataMatcher (route.matcher );
284+ auto dh = header::DataHeader (concrete.description , concrete.origin , concrete.subSpec );
285+ bool wasAOD = std::ranges::any_of (route.matcher .metadata , [](ConfigParamSpec const & p) { return p.name .starts_with (" aod-origin-replaced" ); });
286+
287+ try {
288+ if (!didir->readTree (outputs, dh, fcnt, ntf, totalSizeCompressed, totalSizeUncompressed, wasAOD)) {
289+ if (firstTable && !triedNextFile) {
290+ readState = TFReaderState::TRY_NEXT_FILE ;
291+ break ;
315292 }
316- skipInvalidRead ( concrete.origin , e );
317- return ;
293+ LOGP (fatal, " Can not retrieve tree for table {}: fileCounter {}, timeFrame {} " , concrete.origin . as <std::string>(), fcnt, ntf );
294+ throw std::runtime_error ( " Processing is stopped! " ) ;
318295 }
319- readState = ReadState::FIRST_READ ;
296+ } catch (InvalidAODReadError const & e) {
297+ if (!skipInvalidReads) {
298+ throw ;
299+ }
300+ skipInvalidRead (concrete.origin , e);
301+ readState = TFReaderState::INVALID_TIMEFRAME ;
320302 break ;
321- case ReadState::BEFORE_FIRST_READ :
322- throw std::logic_error (" Invalid AOD read state" );
323- }
324-
325- if (readState == ReadState::FIRST_READ ) {
326- if (reportTFN) {
327- // TF number
328- auto timeFrameNumber = didir->getTimeFrameNumber (dh, fcnt, ntf);
329- auto o = Output (TFNumberHeader);
330- outputs.make <uint64_t >(o) = timeFrameNumber;
331303 }
332304
333- if (reportTFFileName) {
334- // Origin file name for derived output map
335- auto o2 = Output (TFFileNameHeader);
336- auto fileAndFolder = didir->getFileFolder (dh, fcnt, ntf);
337- auto rootFS = std::dynamic_pointer_cast<TFileFileSystem>(fileAndFolder.filesystem ());
338- auto * f = dynamic_cast <TFile*>(rootFS->GetFile ());
339- std::string currentFilename (f->GetFile ()->GetName ());
340- if (strcmp (f->GetEndpointUrl ()->GetProtocol (), " file" ) == 0 && f->GetEndpointUrl ()->GetFile ()[0 ] != ' /' ) {
341- // This is not an absolute local path. Make it absolute.
342- static std::string pwd = gSystem ->pwd () + std::string (" /" );
343- currentFilename = pwd + std::string (f->GetName ());
305+ if (firstTable) {
306+ if (reportTFN) {
307+ // TF number
308+ auto timeFrameNumber = didir->getTimeFrameNumber (dh, fcnt, ntf);
309+ auto o = Output (TFNumberHeader);
310+ outputs.make <uint64_t >(o) = timeFrameNumber;
311+ }
312+
313+ if (reportTFFileName) {
314+ // Origin file name for derived output map
315+ auto o2 = Output (TFFileNameHeader);
316+ auto fileAndFolder = didir->getFileFolder (dh, fcnt, ntf);
317+ auto rootFS = std::dynamic_pointer_cast<TFileFileSystem>(fileAndFolder.filesystem ());
318+ auto * f = dynamic_cast <TFile*>(rootFS->GetFile ());
319+ std::string currentFilename (f->GetFile ()->GetName ());
320+ if (strcmp (f->GetEndpointUrl ()->GetProtocol (), " file" ) == 0 && f->GetEndpointUrl ()->GetFile ()[0 ] != ' /' ) {
321+ // This is not an absolute local path. Make it absolute.
322+ static std::string pwd = gSystem ->pwd () + std::string (" /" );
323+ currentFilename = pwd + std::string (f->GetName ());
324+ }
325+ outputs.make <std::string>(o2) = currentFilename;
344326 }
345- outputs.make <std::string>(o2) = currentFilename;
346327 }
328+ firstTable = false ;
347329 }
348- readState = ReadState::READ ;
330+ }
331+
332+ switch (readState) {
333+ case TFReaderState::TIMEFRAME_READ :
334+ break ;
335+ case TFReaderState::INVALID_TIMEFRAME :
336+ return ;
337+ case TFReaderState::END_OF_INPUT :
338+ LOGP (info, " No input files left to read for reader {}!" , device.inputTimesliceId );
339+ didir->closeInputFiles ();
340+ monitoring.flushBuffer ();
341+ control.endOfStream ();
342+ control.readyToQuit (QuitRequest::Me);
343+ return ;
344+ case TFReaderState::READ_TIMEFRAME :
345+ case TFReaderState::TRY_NEXT_FILE :
346+ throw std::logic_error (" Invalid timeframe read state" );
349347 }
350348 int64_t stopSize = totalSizeCompressed;
351349 int64_t bytesDelta = stopSize - startSize;
0 commit comments