/data3/calcul/jacquem/working_dir/Micromegas/micromegasFrameWork/lcio/src/cpp/src/SIO/LCIORandomAccessMgr.cc

Go to the documentation of this file.
00001 #include "SIO/LCIORandomAccessMgr.h"
00002 
00003 #include "SIO/LCSIO.h"
00004 #include "SIO/SIORandomAccessHandler.h"
00005 #include "SIO/SIOIndexHandler.h"
00006 #include "SIO/SIOEventHandler.h"
00007 #include "SIO/SIORunHeaderHandler.h"
00008 
00009 #include "IOIMPL/LCEventIOImpl.h"
00010 #include "IOIMPL/LCRunHeaderIOImpl.h"
00011 
00012 #include "SIO_stream.h"
00013 #include "SIO_blockManager.h"
00014 
00015 #include "Exceptions.h"
00016 #include <sstream>
00017 
00018 #include <stdio.h>
00019 #include <string.h>
00020 
00021 using namespace IO ;
00022 
00023 namespace SIO{
00024 
00025 
00026   LCIORandomAccessMgr::LCIORandomAccessMgr() : _fileRecord(0) {
00027   }
00028 
00029   LCIORandomAccessMgr::~LCIORandomAccessMgr() {
00030 
00031     // cleanup 
00032     for( std::list<LCIORandomAccess* >::iterator i = _list.begin() ; i != _list.end() ; ++i ){
00033 
00034       delete *i ; 
00035     }
00036 
00037     if( _fileRecord != 0 ) 
00038       delete _fileRecord ;
00039   }
00040 
00041   LCIORandomAccess* LCIORandomAccessMgr::createFromEventMap() {
00042 
00043     LCIORandomAccess* ra = new LCIORandomAccess  ;
00044     
00045     ra->_minRunEvt =   _runEvtMap.minRunEvent() ;
00046     ra->_maxRunEvt =   _runEvtMap.maxRunEvent() ;
00047     ra->_nRunHeaders = _runEvtMap.getNumberOfRunRecords() ;
00048     ra->_nEvents =     _runEvtMap.getNumberOfEventRecords() ;
00049     
00050     ra->_recordsAreInOrder =  true ;  //  ???? how is this defined ????  
00051     ra->_indexLocation = 0 ;
00052     ra->_prevLocation = 0 ;
00053     ra->_nextLocation = 0 ;
00054     ra->_firstRecordLocation = 0 ;
00055 
00056     return ra ;
00057   }
00058 
00059 
00060 
00061   void LCIORandomAccessMgr::createFileRecord(){
00062 
00063     if( _fileRecord == 0 ) {
00064 
00065       _fileRecord = new LCIORandomAccess ;
00066       
00067       _fileRecord->_minRunEvt = RunEvent( 2147483647L, 2147483647L ) ; // 2**31-1  - largest 32 bit signed 
00068       _fileRecord->_maxRunEvt = 0 ;
00069       _fileRecord->_nRunHeaders = 0 ;
00070       _fileRecord->_nEvents = 0 ;
00071       _fileRecord->_recordsAreInOrder = 1 ;  
00072       _fileRecord->_indexLocation = 0 ; // defines file record
00073       _fileRecord->_prevLocation = 9223372036854775807LL ; // 2**63-1  - largest 64 bit signed 
00074       _fileRecord->_nextLocation = 0 ;
00075       _fileRecord->_firstRecordLocation = 0 ;
00076       
00077     } 
00078     
00079     
00080     for( std::list<LCIORandomAccess* >::const_iterator i = _list.begin() ; i != _list.end() ; ++i ){
00081       LCIORandomAccess* ra = *i ; 
00082       
00083         _fileRecord->_minRunEvt = ( ra->_minRunEvt < _fileRecord->_minRunEvt ?  ra->_minRunEvt : _fileRecord->_minRunEvt  ) ;
00084         _fileRecord->_maxRunEvt = ( ra->_maxRunEvt > _fileRecord->_maxRunEvt ?  ra->_maxRunEvt : _fileRecord->_maxRunEvt  ) ;
00085         _fileRecord->_nRunHeaders += ra->_nRunHeaders ;
00086         _fileRecord->_nEvents += ra->_nEvents ;
00087         _fileRecord->_recordsAreInOrder = ( _fileRecord->_recordsAreInOrder * ra->_recordsAreInOrder  ) ; // should be 0 if any record is 0  
00088         _fileRecord->_indexLocation = 0 ; // defines file record
00089 
00090         if( ra->_nextLocation > _fileRecord->_nextLocation )
00091           _fileRecord->_nextLocation  =  ra->_nextLocation ;
00092         
00093         if( 0 < ra->_prevLocation  &&  ra->_prevLocation < _fileRecord->_prevLocation )
00094           _fileRecord->_prevLocation  =  ra->_prevLocation ;
00095         
00096         
00097         //  _fileRecord->_firstRecordLocation = 0 ;
00098             
00099     }
00100           
00101   }
00102 
00103   void  LCIORandomAccessMgr::addLCIORandomAccess( LCIORandomAccess* ra ) { 
00104     
00105     _list.push_back( ra ) ; 
00106     
00107     //       _list.sort() ;
00108     //       for( std::list<LCIORandomAccess* >::const_iterator i = _list.begin() ; i != _list.end() ; ++i ){
00109 //      std::cout << "++++++++++++++++++++++++++++++++++++++ "  << **i ; 
00110 //       }
00111 
00112     }
00113 
00114 
00115   bool LCIORandomAccessMgr::readLCIORandomAccessAt( SIO_stream* stream , long64 pos) {
00116     
00117     LCSIO::seekStream( stream, pos ) ;
00118 
00119     return readLCIORandomAccess( stream ) ;
00120   }
00121 
00122 
00123   bool LCIORandomAccessMgr::readLCIORandomAccess( SIO_stream* stream ) {
00124 
00125     SIO_record* accessRecord = LCSIO::records()[ SIORecords::Access ] ;
00126     
00127     SIORecords::Unpack raUnp( SIORecords::Unpack::All ) ;
00128     
00129     SIORandomAccessHandler raHandler( LCSIO_ACCESSRECORDNAME,  this ) ;
00130     
00131     SIO_blockManager::remove(  LCSIO_ACCESSRECORDNAME ) ;
00132     SIO_blockManager::add( &raHandler ) ;
00133     
00134     int status =  stream->read( &accessRecord ) ;
00135     
00136     if( ! (status & 1)  ){
00137       
00138       status = stream->reset() ;
00139       
00140       if( status != SIO_STREAM_SUCCESS ){
00141         
00142         throw IOException( std::string(" io error  reading LCIORandomAccess on stream: ") 
00143                            + *stream->getName() ) ;
00144       }
00145       
00146       // std::cout << " ... no LCIORandomAccess record found - old file ??? " << std::endl ;
00147       
00148       return false ;
00149     }
00150     
00151     //    std::cout << " ...  LCIORandomAccess record found - return true ;-) " << std::endl ;
00152 
00153     return true ;
00154   }
00155 
00156   bool LCIORandomAccessMgr::readLCIOIndexAt( SIO_stream* stream , long64 pos) {
00157 
00158     LCSIO::seekStream( stream, pos ) ;
00159 
00160     return readLCIOIndex( stream ) ;
00161   }
00162 
00163   bool LCIORandomAccessMgr::readLCIOIndex( SIO_stream* stream ) {
00164 
00165     SIORecords::Unpack raUnp( SIORecords::Unpack::All ) ;
00166     
00167     SIOIndexHandler raHandler( LCSIO_INDEXRECORDNAME,  this ) ;
00168     
00169     SIO_blockManager::remove( LCSIO_INDEXRECORDNAME  ) ;
00170     SIO_blockManager::add( &raHandler ) ;
00171     
00172     SIO_record* indexRecord = LCSIO::records()[ SIORecords::Index ] ;
00173 
00174     int status =  stream->read( &indexRecord ) ;
00175     
00176     if( ! (status & 1)  ){
00177       
00178       status = stream->reset() ;
00179       
00180       if( status != SIO_STREAM_SUCCESS ){
00181           
00182         throw IOException( std::string(" io error  reading LCIOIndex on stream: ") 
00183                            + *stream->getName() ) ;
00184       }
00185       
00186       std::cout << " ... no LCIOIndex record found - old file ??? " << std::endl ;
00187       
00188       return false ;
00189     }
00190     
00191     return true ;
00192   }
00193 
00194 
00195   bool LCIORandomAccessMgr::initAppend( SIO_stream* stream ) {
00196     
00197     // check if the last record is LCIORandomAccess  (the file record )
00198     if( ! readLCIORandomAccessAt( stream , -LCSIO_RANDOMACCESS_SIZE) )  {
00199       
00200       recreateEventMap( stream ) ; 
00201       
00202       return false;
00203     }
00204     
00205     // store the file record separately 
00206     _fileRecord = _list.back() ;
00207     _list.pop_back()  ;
00208 
00209     // now read first LCIORandomAccess record 
00210     readLCIORandomAccessAt( stream ,   _fileRecord->_nextLocation    ) ; // start of last LCIORandomAccessRecord        
00211 
00212     return true ;
00213   }
00214 
00215 
00216   bool LCIORandomAccessMgr::getEventMap( SIO_stream* stream ) {
00217 
00218     // check if the last record is LCIORandomAccess ( the file record )
00219     if( ! readLCIORandomAccessAt( stream , -LCSIO_RANDOMACCESS_SIZE) )  {
00220 
00221       return recreateEventMap( stream ) ; 
00222     }
00223 
00224     // store the file record separately 
00225     _fileRecord = _list.back() ;
00226     _list.pop_back()  ;
00227 
00228     // no read first LCIORandomAccess record 
00229     readLCIORandomAccessAt( stream ,   _fileRecord->_nextLocation    ) ; // start of last LCIORandomAccessRecord        
00230 
00231 
00232     // and then read all remaining LCIORandomAccess records
00233 
00234     const LCIORandomAccess* ra = lastLCIORandomAccess() ;
00235 
00236     EVENT::long64 raPos = ra->getPrevLocation() ;
00237 
00238     EVENT::long64 indexPos = ra->getIndexLocation() ;
00239     
00240     readLCIOIndexAt( stream , indexPos ) ;
00241 
00242     while( raPos != 0 ){
00243 
00244       if( readLCIORandomAccessAt( stream , raPos) ){
00245 
00246         ra = lastLCIORandomAccess() ;
00247 
00248         raPos = ra->getPrevLocation() ; 
00249 
00250         //      std::cout << " read ra at " << ra << " : " << *ra << "  - prevPos : " << raPos << std::endl ;
00251 
00252         EVENT::long64 indexPos = ra->getIndexLocation() ;
00253 
00254         readLCIOIndexAt( stream , indexPos ) ;
00255 
00256       }else{
00257         throw IOException( std::string( "[LCIORandomAccessMgr::ReadEventMap()] Could not read previous LCIORandomAccess record" ) ) ;
00258       }      
00259     }
00260 
00261     LCSIO::seekStream( stream, 0 ) ;// go to start of file
00262 
00263     return true ;
00264 
00265     //    std::cout << " ... LCIORandomAccess read from stream : "<< *ra << std::endl ;
00266   }
00267 
00268   bool LCIORandomAccessMgr::recreateEventMap( SIO_stream* stream ) {
00269 
00270     std::cout << " LCIORandomAccessMgr::getEventMap() recreating event map for direct access (old file) ..." 
00271               << std::endl ;
00272 
00273     LCSIO::seekStream( stream, 0 ) ;// go to start of file
00274     
00275     
00276     SIO_record* dummyRecord ; 
00277     IOIMPL::LCEventIOImpl* evtPtr ;
00278     IOIMPL::LCRunHeaderIOImpl* runPtr ;
00279     
00280     SIORunHeaderHandler runHandler( LCSIO_RUNBLOCKNAME, &runPtr ) ;
00281     SIOEventHandler eventHandler( LCSIO_HEADERBLOCKNAME, &evtPtr ) ;
00282     
00283     SIO_blockManager::remove(  LCSIO_HEADERBLOCKNAME ) ;
00284     SIO_blockManager::add( &eventHandler ) ;
00285     SIO_blockManager::remove(  LCSIO_RUNBLOCKNAME ) ;
00286     SIO_blockManager::add( &runHandler ) ;
00287     
00288     { // -- scope for unpacking evt and run headers  --------
00289       SIORecords::Unpack hdrUnp( SIORecords::Unpack::Header + SIORecords::Unpack::Run ) ;
00290       
00291       while( true ){
00292         
00293         
00294         //----    readRecord() ;
00295         // read the next record from the stream
00296         if( stream->getState()== SIO_STATE_OPEN ){
00297           
00298           unsigned int status =  stream->read( &dummyRecord ) ;
00299           
00300           if( ! (status & 1)  ){
00301             
00302             if( status & SIO_STREAM_EOF ){
00303               break ;
00304             }
00305             
00306             throw IOException( std::string(" io error on stream: ") + *stream->getName() ) ;
00307           }
00308         } else {
00309           throw IOException( std::string(" stream not open: ")+ *stream->getName() ) ;
00310         }
00311         
00312         //--
00313         int runNum = -1 ;
00314         int evtNum = -1 ;
00315         
00316         if( ! strcmp( dummyRecord->getName()->c_str() , LCSIO_HEADERRECORDNAME )){
00317           
00318           runNum = evtPtr->getRunNumber() ;
00319           evtNum = evtPtr->getEventNumber() ;
00320         }
00321         if( ! strcmp( dummyRecord->getName()->c_str() , LCSIO_RUNRECORDNAME )){
00322           
00323           runNum = runPtr->getRunNumber() ;
00324         }
00325         
00326         _runEvtMap.add(   RunEvent( runNum , evtNum ) ,  stream->lastRecordStart() ) ;
00327         
00328         
00329         //      EVENT::long64 key  = (EVENT::long64( runNum ) << 32 ) | evtNum ;
00330         //      std::cout << "  " <<  key << " - " << stream->lastRecordStart()  
00331         //                << " evt: " << evtNum << std::endl ;
00332         
00333       } // while
00334       
00335       
00336       LCSIO::seekStream( stream, 0 ) ;// go to start of file
00337 
00338     }// -- end of scope for unpacking evt header --
00339     
00340     //     std::cout << " LCIORandomAccessMgr::getEventMap() : done " << std::endl ;
00341     
00342     return true ;
00343   }
00344   
00345   void LCIORandomAccessMgr::writeRandomAccessRecords(SIO_stream* stream) {
00346     
00347     if( _runEvtMap.empty() ) { 
00348       return ;       // nothing to write          
00349     }
00350     //-------------------------------------
00351 
00352     SIO_record* accessRecord = LCSIO::records()[ SIORecords::Access ] ;
00353     SIO_record* indexRecord  = LCSIO::records()[ SIORecords::Index ] ;
00354     
00355     SIORandomAccessHandler raHandler (  LCSIO_ACCESSRECORDNAME, this ) ;
00356     SIOIndexHandler idxHandler(  LCSIO_INDEXRECORDNAME,   this ) ;
00357     
00358     accessRecord->connect( &raHandler ) ;
00359     indexRecord->connect( &idxHandler ) ;
00360     
00361     
00362     if( stream->getState() != SIO_STATE_OPEN ){
00363       throw IOException( std::string( "[LCIORandomAccessMgr::writeRandomAccessRecords] stream not opened: "
00364                                       +  *stream->getName() ) ) ;
00365     }
00366 
00367     //    LCSIO::records().setCompress( _compressionLevel != 0 ) ; 
00368     
00369     // write LCIOIndex record
00370     unsigned int status =  stream->write( LCSIO_INDEXRECORDNAME    ) ;
00371     
00372     if( !(status & 1)  )
00373       throw IOException( std::string( "[LCIORandomAccessMgr::writeRandomAccessRecords] couldn't write LCIOIndex to stream: "
00374                                       +  *stream->getName() ) ) ;
00375 
00376 
00377 
00378     // create the LCIORandomAccess object ( linked list of records ) 
00379     LCIORandomAccess* ra = createFromEventMap() ;
00380     
00381     ra->setIndexLocation( stream->lastRecordStart() ) ;
00382 
00383     //FIXME: mis-use getFirstRecordLocation for now - should become an attribute : "thisLocation"
00384     long64 thisPos = stream->currentPosition() ;
00385     ra->setFirstRecordLocation(  thisPos  ) ;
00386 
00387     const LCIORandomAccess* lRa  = lastLCIORandomAccess() ;
00388 
00389     EVENT::long64 prevPos = (  lRa ? lRa->getFirstRecordLocation()  : 0 ) ;
00390 
00391     //    std::cout << " setting previous location : " << prevPos << "  from last ra : " << lRa << std::endl ;  
00392 
00393     ra->setPreviousLocation(  prevPos ) ;
00394 
00395 
00396     // the last LCIORandomAccess object will be written to the file by the SIORandomAccessHandler
00397     addLCIORandomAccess( ra ) ; 
00398     
00399     
00400     // write LCAccess record
00401     status =  stream->write( LCSIO_ACCESSRECORDNAME    ) ;
00402     
00403     if( !(status & 1)  )
00404       throw IOException( std::string( "[LCIORandomAccessMgr::writeRandomAccessRecords] couldn't write LCIORandomAccess to stream: "
00405                                       +  *stream->getName() ) ) ;
00406     
00407 
00408 
00409     //--------  now we write the file record at the end -------------------------------------
00410 
00411     createFileRecord() ;
00412 
00413     if( thisPos > _fileRecord->_nextLocation )
00414       _fileRecord->_nextLocation  =  thisPos ;
00415     
00416     if( _fileRecord->_prevLocation > thisPos )
00417       _fileRecord->_prevLocation  =  thisPos ;
00418 
00419     addLCIORandomAccess( _fileRecord ) ; 
00420     
00421     status =  stream->write( LCSIO_ACCESSRECORDNAME    ) ;
00422     
00423     if( !(status & 1)  )
00424       throw IOException( std::string( "[LCIORandomAccessMgr::writeRandomAccessRecords] couldn't write LCIORandomAccess file record to stream: "
00425                                       +  *stream->getName() ) ) ;
00426     
00427     
00428     _list.pop_back()  ;
00429 
00430   }
00431   
00432 
00433 
00434   //---------------------------------------------
00435 
00436   std::ostream& operator<<(std::ostream& os, const LCIORandomAccessMgr& ra ){
00437     
00438     os << " LCIORandomAccessMgr:  ----------------------- " << std::endl   ;
00439     
00440     for( std::list<LCIORandomAccess* >::const_iterator i = ra._list.begin() ; i != ra._list.end() ; ++i ){
00441       
00442       os << **i ; 
00443     }
00444     
00445     os  <<  ra._runEvtMap   << std::endl ;
00446     
00447     return os ;
00448   }
00449 }

Generated on Mon Jan 7 13:15:21 2013 for MicromegasFramework by  doxygen 1.4.7