00001
00002
00003
00004
00005
00006
00007
00008 #include "BaBar/BaBar.hh"
00009
00010 #include "CdbRooConversionFwk/CdbBdb2RooPayloadConversionFwk.hh"
00011
00012 #include "CdbBase/CdbId.hh"
00013 #include "CdbBase/CdbDatabase.hh"
00014 #include "CdbBase/CdbOrigin.hh"
00015 #include "CdbBase/CdbPartition.hh"
00016 #include "CdbBase/CdbCondition.hh"
00017 #include "CdbBase/CdbTransaction.hh"
00018 #include "CdbBase/CdbStringUtils.hh"
00019
00020 #include "BdbCond/BdbObject.hh"
00021
00022 #include "CdbBdb/CdbBdbSchemaUtils.hh"
00023
00024 #include "CdbBdbShared/CdbBdbShared.hh"
00025
00026 #include "CdbRoo/CdbRooObjectR.hh"
00027 #include "CdbRoo/CdbRooObjectHasMovedR.hh"
00028
00029 #include "CdbRooReadonly/CdbRooReadonly.hh"
00030 #include "CdbRooReadonly/CdbRooRoFileUtils.hh"
00031 #include "CdbRooReadonly/CdbRooRoMetaDataR.hh"
00032 #include "CdbRooReadonly/CdbRooRoOiCollectionR.hh"
00033 #include "CdbRooReadonly/CdbRooRoObjectIdR.hh"
00034
00035 #include "CdbRooConversionFwk/CdbRooConverterBase.hh"
00036 #include "CdbRooConversionFwk/CdbBdb2RooPayloadConvertersDict.hh"
00037 #include "CdbRooConversionFwk/CdbRooConverterDict.hh"
00038
00039 #include <stdio.h>
00040
00041 #include <TDirectory.h>
00042 #include <TTree.h>
00043 #include <TBranch.h>
00044
00045 #include <string>
00046 #include <vector>
00047 #include <map>
00048 #include <iostream>
00049 using std::cin;
00050 using std::cout;
00051 using std::cerr;
00052 using std::endl;
00053
00054 #include <fstream>
00055 using std::ifstream;
00056
00057 #include <sstream>
00058 using std::ostringstream;
00059
00060 #include "BbrStdUtils/Tokenize.hh"
00061 #include "BbrStdUtils/String.hh"
00062 using namespace babar::String;
00063
00064 namespace {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template< class T >
00075 std::string
00076 vector2string( const std::vector<T>& theVector )
00077 {
00078 ostringstream result;
00079 for( typename std::vector<T>::const_iterator itr = theVector.begin( );
00080 itr != theVector.end( );
00081 ++itr ) {
00082 result << (*itr) << " ";
00083 }
00084 return result.str( );
00085 }
00086
00087
00088
00089 bool translate_OID( ooRef(ooObj)& theRef,
00090 const std::string& theString )
00091 {
00092 assert( !theString.empty( ));
00093
00094 ooId id;
00095 {
00096 int db;
00097 int cont;
00098 int page;
00099 int slot;
00100
00101 if( 4 != sscanf( theString.c_str( ), "#%d-%d-%d-%d", &db, &cont, &page, &slot )) {
00102 if( 4 != sscanf( theString.c_str( ), "%d-%d-%d-%d", &db, &cont, &page, &slot )) {
00103 return false;
00104 }
00105 }
00106
00107 id.set_DB ( db );
00108 id.set_OC ( cont );
00109 id.set_page( page );
00110 id.set_slot( slot );
00111 }
00112 theRef = id;
00113
00114 return true;
00115 }
00116
00117
00118
00119 struct CdbBdb2RooPayloadMetaDataDescriptor {
00120
00121
00122
00123 CdbBdb2RooPayloadMetaDataDescriptor( UShort_t theOriginId,
00124 UShort_t theConditionId,
00125 bool isPartitionableFlag,
00126 UShort_t thePartitionId,
00127 UShort_t theClusterId,
00128 UShort_t theIncrementId ) :
00129 originId (theOriginId),
00130 conditionId (1, theConditionId),
00131 isPartitionable(isPartitionableFlag),
00132 partitionId (thePartitionId),
00133 clusterId (theClusterId),
00134 incrementId (theIncrementId)
00135 { }
00136
00137
00138
00139 CdbBdb2RooPayloadMetaDataDescriptor( UShort_t theOriginId,
00140 const std::vector< UShort_t >& theConditionId,
00141 bool isPartitionableFlag,
00142 UShort_t thePartitionId,
00143 UShort_t theClusterId,
00144 UShort_t theIncrementId ) :
00145 originId (theOriginId),
00146 conditionId (theConditionId),
00147 isPartitionable(isPartitionableFlag),
00148 partitionId (thePartitionId),
00149 clusterId (theClusterId),
00150 incrementId (theIncrementId)
00151 { }
00152
00153 std::string toString( ) const
00154 {
00155 ostringstream result;
00156 result << originId << "::" << conditionId[0] << " [" << partitionId << "," << clusterId << "," << incrementId << "] ";
00157 return result.str( );
00158 }
00159
00160 UShort_t originId;
00161 std::vector< UShort_t > conditionId;
00162 bool isPartitionable;
00163 UShort_t partitionId;
00164 UShort_t clusterId;
00165 UShort_t incrementId;
00166 };
00167
00168
00169
00170 void printMetDataParameters( UShort_t theOriginId,
00171 UShort_t theConditionId,
00172 bool isPartitionableFlag,
00173 UShort_t thePartitionId,
00174 UShort_t theClusterId,
00175 UShort_t theIncrementId )
00176 {
00177 cout << " Origin identifier : " << theOriginId << endl
00178 << " Condition identifier : " << theConditionId << endl
00179 << " Is partitionable : " << ( isPartitionableFlag ? "Yes" : "No" ) << endl
00180 << " Partition identifier : " << thePartitionId << endl
00181 << " Cluster identifier : " << theClusterId << endl
00182 << " Increment number : " << theIncrementId << endl;
00183 }
00184
00185
00186
00187 struct CdbBdb2RooPayloadContainerContext {
00188
00189 CdbBdb2RooPayloadContainerContext( const std::string& theTreeName,
00190 const std::string& theTreeDescription,
00191 const CdbCPtr<CdbRooConverterBase>& theConverterPtr ) :
00192 tree( theTreeName.c_str( ),
00193 theTreeDescription.c_str( )),
00194 converterPtr(theConverterPtr)
00195 { }
00196
00197 void add( const BdbRef(BdbObject)& theInputLegacyObjectRef,
00198 const CdbRooRoObjectIdR& theOutputObjectId )
00199 {
00200 inObjects.push_back( theInputLegacyObjectRef );
00201 outObjects.push_back( theOutputObjectId );
00202 }
00203
00204
00205
00206 TTree tree;
00207
00208 CdbCPtr<CdbRooConverterBase> converterPtr;
00209
00210 std::vector< BdbRef(BdbObject) > inObjects;
00211 std::vector< CdbRooRoObjectIdR > outObjects;
00212 };
00213
00214 struct CdbBdb2RooPayloadMainContainerContext {
00215
00216 CdbBdb2RooPayloadMainContainerContext( const std::string& theTreeName,
00217 const std::string& theTreeDescription,
00218 const CdbCPtr<CdbRooConverterBase>& theConverterPtr ) :
00219 tree( theTreeName.c_str( ),
00220 theTreeDescription.c_str( )),
00221 converterPtr(theConverterPtr)
00222 { }
00223
00224 void add( const std::vector< BdbRef(BdbObject) >& theInputLegacyObjectRef,
00225 const CdbRooRoObjectIdR& theOutputObjectId )
00226 {
00227 inObjects.push_back( theInputLegacyObjectRef );
00228 outObjects.push_back( theOutputObjectId );
00229 }
00230
00231
00232
00233 TTree tree;
00234
00235 CdbCPtr<CdbRooConverterBase> converterPtr;
00236
00237 std::vector< std::vector< BdbRef(BdbObject) > > inObjects;
00238 std::vector< CdbRooRoObjectIdR > outObjects;
00239 };
00240 struct CdbBdb2RooPayloadExtraContainerContext {
00241
00242 CdbBdb2RooPayloadExtraContainerContext( const std::string& theTreeName,
00243 const std::string& theTreeDescription,
00244 const CdbCPtr<CdbRooConverterBase>& theConverterPtr ) :
00245 tree( theTreeName.c_str( ),
00246 theTreeDescription.c_str( )),
00247 converterPtr(theConverterPtr)
00248 { }
00249
00250 void add( const BdbRef(BdbObject)& theInputLegacyObjectRef,
00251 const CdbRooRoObjectIdR& theOutputObjectId,
00252 const CdbRooRoObjectIdR& theMainObjectId )
00253 {
00254 inObjects.push_back( theInputLegacyObjectRef );
00255 outObjects.push_back( theOutputObjectId );
00256 mainObjects.push_back( theMainObjectId );
00257 }
00258
00259
00260
00261 TTree tree;
00262
00263 CdbCPtr<CdbRooConverterBase> converterPtr;
00264
00265 std::vector< BdbRef(BdbObject) > inObjects;
00266 std::vector< CdbRooRoObjectIdR > outObjects;
00267 std::vector< CdbRooRoObjectIdR > mainObjects;
00268 };
00269
00270 bool translateNextLine( const std::string& theLine,
00271 const CdbDatabasePtr& theDatabasePtr,
00272 UShort_t& theOriginId,
00273 UShort_t& theConditionId,
00274 bool& isPartitionableFlag,
00275 UShort_t& thePartitionId,
00276 UShort_t& theClusterId,
00277 UShort_t& theIncrementId,
00278 std::string& theInputClassName )
00279 {
00280 const char* errorStr = "CdbBdb2RooPayloadConversionFwk::<anonymous>::translateNextLine() - ERROR.";
00281
00282 Tokenize tokenize( theLine );
00283
00284 std::string physicalConditionId = tokenize( );
00285 std::string placementInfo = tokenize( );
00286 std::string spaceFilledSeparator = tokenize( "\"" );
00287 std::string inputClassName = tokenize( "\"" );
00288
00289 if( physicalConditionId.empty( ) ||
00290 placementInfo.empty( ) ||
00291 spaceFilledSeparator.empty( ) ||
00292 inputClassName.empty( )) {
00293
00294 cerr << errorStr << endl
00295 << " The line read from the definition file has an illegal format." << endl
00296 << "\"" << theLine << "\"" << endl;
00297 return false;
00298 }
00299
00300 UShort_t originId = 0;
00301 UShort_t conditionId = 0;
00302 {
00303 unsigned origin;
00304 unsigned local;
00305
00306 if( 2 != sscanf( physicalConditionId.c_str( ), "%u::%u", &origin, &local )) {
00307 cerr << errorStr << endl
00308 << " Failed to translate the physical identifier of the condition found" << endl
00309 << " at the following line of the definition file." << endl
00310 << "\"" << theLine << "\"" << endl;
00311 return false;
00312 }
00313 if(( origin > 0xFFFF ) || ( local > 0xFFFF )) {
00314 cerr << errorStr << endl
00315 << " The translated physical identifier of the condition has illegal format." << endl
00316 << " The identifier was found at the following line of the definition file." << endl
00317 << "\"" << theLine << "\"" << endl;
00318 return false;
00319 }
00320 originId = (UShort_t)origin;
00321 conditionId = (UShort_t)local;
00322 }
00323
00324 bool isPartitionable = false;
00325 {
00326 CdbId physicalId( originId,
00327 conditionId );
00328
00329 CdbConditionPtr cPtr;
00330 if( CdbStatus::Success != CdbCondition::instance( cPtr,
00331 physicalId )) {
00332 cerr << errorStr << endl
00333 << " Failed to find the condition with the condition physical identifier " << physicalId << endl
00334 << " in the input federation." << endl;
00335 return false;
00336 }
00337 isPartitionable = cPtr->isPartitionable( );
00338 }
00339
00340 UShort_t partitionId = 0;
00341 UShort_t clusterId = 0;
00342 UShort_t incrementId = 0;
00343 {
00344 unsigned partition;
00345 unsigned cluster;
00346 unsigned increment;
00347
00348 if( 3 != sscanf( placementInfo.c_str( ), "[%u,%u,%u]", &partition, &cluster, &increment )) {
00349 cerr << errorStr << endl
00350 << " Failed to translate the condition placement parameters found" << endl
00351 << " at the following line of the definition file." << endl
00352 << "\"" << theLine << "\"" << endl;
00353 return false;
00354 }
00355 if(( partition > 0xFFFF ) || ( cluster > 0xFFFF ) || ( increment > 0xFFFF )) {
00356 cerr << errorStr << endl
00357 << " The translated condition placement parameters have illegal format." << endl
00358 << " They were found at the following line of the definition file." << endl
00359 << "\"" << theLine << "\"" << endl;
00360 return false;
00361 }
00362 partitionId = (UShort_t)partition;
00363 clusterId = (UShort_t)cluster;
00364 incrementId = (UShort_t)increment;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 if( isPartitionable ) {
00374
00375 CdbPartitionPtr partitionPtr;
00376 if( CdbStatus::Success != theDatabasePtr->findPartition( partitionPtr,
00377 partitionId )) {
00378 cerr << errorStr << endl
00379 << " Failed to obtain a pointer onto the CDB API object for the partition " << partitionId << endl;
00380 return false;
00381 }
00382 originId = partitionPtr->ownerId( );
00383 }
00384
00385
00386
00387 theOriginId = originId;
00388 theConditionId = conditionId;
00389 isPartitionableFlag = isPartitionable;
00390 thePartitionId = partitionId;
00391 theClusterId = clusterId;
00392 theIncrementId = incrementId;
00393 theInputClassName = inputClassName;
00394
00395 return true;
00396 }
00397 }
00398
00399
00400
00401
00402
00403 bool CdbBdb2RooPayloadConversionFwk::verboseModeFlag = true;
00404 bool CdbBdb2RooPayloadConversionFwk::debugModeFlag = false;
00405 bool CdbBdb2RooPayloadConversionFwk::doNotCompressModeFlag = false;
00406
00407
00408
00409
00410
00411 bool
00412 CdbBdb2RooPayloadConversionFwk::setVerbose( bool newModeFlag )
00413 {
00414 bool previousFlag = verboseModeFlag;
00415 verboseModeFlag = newModeFlag;
00416 return previousFlag;
00417 }
00418
00419 bool
00420 CdbBdb2RooPayloadConversionFwk::setDebug( bool newModeFlag )
00421 {
00422 bool previousFlag = debugModeFlag;
00423 debugModeFlag = newModeFlag;
00424 return previousFlag;
00425 }
00426
00427 bool
00428 CdbBdb2RooPayloadConversionFwk::setDoNotCompress( bool newModeFlag )
00429 {
00430 bool previousFlag = doNotCompressModeFlag;
00431 doNotCompressModeFlag = newModeFlag;
00432 return previousFlag;
00433 }
00434
00435 CdbStatus
00436 CdbBdb2RooPayloadConversionFwk::registerConverter( const CdbCPtr< CdbRooConverterBase >& thePtr )
00437 {
00438 if( thePtr.isNull( )) return CdbStatus::IllegalParameters;
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 if( thePtr->mergingConverter( )) return mergingConvertersDict( )->add( thePtr );
00449 return regularConvertersDict( )->add( thePtr );
00450 }
00451
00452 CdbStatus
00453 CdbBdb2RooPayloadConversionFwk::registerConverters(const std::vector< CdbCPtr < CdbRooConverterDict > >& theDicts)
00454 {
00455 vector< CdbCPtr< CdbRooConverterDict > >::const_iterator iter = theDicts.begin();
00456
00457 while (iter != theDicts.end()) {
00458
00459 vector< CdbCPtr< CdbRooConverterBase > > vect = (*iter)->converters();
00460 vector< CdbCPtr< CdbRooConverterBase > >::iterator converterIter = vect.begin();
00461
00462 while (converterIter != vect.end()) {
00463 CdbStatus result = registerConverter(*converterIter);
00464 if (result != CdbStatus::Success) return result;
00465 converterIter++;
00466 }
00467
00468 iter++;
00469 }
00470
00471 return CdbStatus::Success;
00472 }
00473
00474 CdbStatus
00475 CdbBdb2RooPayloadConversionFwk::testConversion( UShort_t theOriginId,
00476 UShort_t theConditionId,
00477 bool isPartitionableFlag,
00478 UShort_t thePartitionId,
00479 UShort_t theClusterId,
00480 UShort_t theIncrementId )
00481 {
00482 const char* infoStr = "CdbBdb2RooPayloadConversionFwk::testConversion(regular) - INFO.";
00483
00484 cout << infoStr << endl
00485 << " Just for the record, you've entered the following parameters:" << endl
00486 << endl
00487 << " Origin identifier : " << theOriginId << endl
00488 << " Condition identifier : " << theConditionId << endl
00489 << " Is partitionable : " << ( isPartitionableFlag ? "Yes" : "No" ) << endl
00490 << " Partition identifier : " << thePartitionId << endl
00491 << " Cluster identifier : " << theClusterId << endl
00492 << " Increment number : " << theIncrementId << endl
00493 << endl;
00494
00495
00496
00497 CdbBdbShared::forceLoad( );
00498
00499 CdbTransaction bdbReadOnlyTransactionStartsHere( CdbBdbShared::technology( ),
00500 CdbBdbShared::implementation( ));
00501
00502
00503
00504 CdbRooReadonly::forceLoad( );
00505
00506 CdbTransaction rooReadOnlyTransactionStartsHere( CdbRooReadonly::technology( ),
00507 CdbRooReadonly::implementation( ));
00508
00509
00510
00511 return convertMetadata( theOriginId,
00512 theConditionId,
00513 isPartitionableFlag,
00514 thePartitionId,
00515 theClusterId,
00516 theIncrementId );
00517 }
00518
00519 CdbStatus
00520 CdbBdb2RooPayloadConversionFwk::testConversion( UShort_t theOriginId,
00521 const std::vector<UShort_t>& theConditionId,
00522 bool isPartitionableFlag,
00523 UShort_t thePartitionId,
00524 UShort_t theClusterId,
00525 UShort_t theIncrementId )
00526 {
00527 const char* infoStr = "CdbBdb2RooPayloadConversionFwk::testConversion(merging) - INFO.";
00528
00529 cout << infoStr << endl
00530 << " Just for the record, you've entered the following parameters:" << endl
00531 << endl
00532 << " Origin identifier : " << theOriginId << endl
00533 << " Condition identifiers : " << ::vector2string( theConditionId ) << endl
00534 << " Is partitionable : " << ( isPartitionableFlag ? "Yes" : "No" ) << endl
00535 << " Partition identifier : " << thePartitionId << endl
00536 << " Cluster identifier : " << theClusterId << endl
00537 << " Increment number : " << theIncrementId << endl
00538 << endl;
00539
00540
00541
00542 CdbBdbShared::forceLoad( );
00543
00544 CdbTransaction bdbReadOnlyTransactionStartsHere( CdbBdbShared::technology( ),
00545 CdbBdbShared::implementation( ));
00546
00547
00548
00549 CdbRooReadonly::forceLoad( );
00550
00551 CdbTransaction rooReadOnlyTransactionStartsHere( CdbRooReadonly::technology( ),
00552 CdbRooReadonly::implementation( ));
00553
00554
00555
00556 return convertMetadata( theOriginId,
00557 theConditionId,
00558 isPartitionableFlag,
00559 thePartitionId,
00560 theClusterId,
00561 theIncrementId );
00562 }
00563
00564 CdbStatus
00565 CdbBdb2RooPayloadConversionFwk::doConversion( const char* theDefinitionFile )
00566 {
00567 const char* errorStr = "CdbBdb2RooPayloadConversionFwk::doConversion() - ERROR.";
00568
00569 CdbStatus result = CdbStatus::Error;
00570
00571 assert( 0 != theDefinitionFile );
00572
00573
00574
00575 CdbBdbShared::forceLoad( );
00576
00577 CdbTransaction bdbReadOnlyTransactionStartsHere( CdbBdbShared::technology( ),
00578 CdbBdbShared::implementation( ));
00579
00580
00581
00582 CdbRooReadonly::forceLoad( );
00583
00584 CdbTransaction rooReadOnlyTransactionStartsHere( CdbRooReadonly::technology( ),
00585 CdbRooReadonly::implementation( ));
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 CdbDatabasePtr databasePtr;
00596 if( CdbStatus::Success != ( result = CdbDatabase::instance( databasePtr ))) {
00597 cerr << errorStr << endl
00598 << " Failed to obtain a pointer onto the CDB API object for the Database." << endl;
00599 return result;
00600 }
00601 if( !databasePtr->localOrigin( )->isMaster( )) {
00602 cerr << errorStr << endl
00603 << " The input CDB is not of the MASTER type. The converter can only be run" << endl
00604 << " against a MASTER type CDB. Make sure that you have set the correct" << endl
00605 << " value for the OO_FD_BOOT environment variable." << endl;
00606 return CdbStatus::Error;
00607 }
00608
00609
00610
00611
00612 typedef std::map< std::string, std::vector< CdbBdb2RooPayloadMetaDataDescriptor > > DescriptorsOfAcceptedMetaData;
00613
00614 DescriptorsOfAcceptedMetaData regularMetaDataDescr;
00615 DescriptorsOfAcceptedMetaData mergedMetaDataDescr;
00616
00617 UShort_t mergedOriginId = 0;
00618 std::vector< UShort_t > mergedConditionId ( 0 );
00619 bool mergedIsPartitionable = false;
00620 UShort_t mergedPartitionId = 0;
00621 UShort_t mergedClusterId = 0;
00622 UShort_t mergedIncrementId = 0;
00623 std::string mergedInputClassName = "";
00624
00625 unsigned int currentLineNumber = 0;
00626 std::string currentLine = "";
00627
00628 enum {
00629 PARSER_IDLE,
00630 PARSER_REGULAR,
00631 PARSER_MERGING_BEGIN,
00632 PARSER_MERGING,
00633 PARSER_FAILED
00634 } parserState = PARSER_IDLE;
00635
00636 ifstream definitionFileStream( theDefinitionFile );
00637
00638 const int bufSize = 64 * 1024;
00639 char buf[bufSize];
00640
00641 while( definitionFileStream.getline( buf,
00642 bufSize, '\n' )) {
00643
00644 ++currentLineNumber;
00645 currentLine = std::string( buf );
00646
00647
00648
00649 if( verboseModeFlag ) {
00650 cout << "translating line: \"" << currentLine << "\"" << endl;
00651 }
00652 if( "#REGULAR" == currentLine ) {
00653
00654 if(( PARSER_IDLE == parserState ) || ( PARSER_REGULAR == parserState ) || ( PARSER_MERGING_BEGIN == parserState )) {
00655
00656 parserState = PARSER_REGULAR;
00657
00658 } else if( PARSER_MERGING == parserState ) {
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 if( mergedConditionId.size( ) > 1 ) {
00672
00673
00674
00675
00676 CdbCPtr<CdbRooConverterBase> converterPtr =
00677 mergingConvertersDict( )->findByInputClassName( mergedInputClassName );
00678
00679 if( converterPtr.isNull( )) {
00680
00681 if( verboseModeFlag ) {
00682 cout << "skipping merged block of MetaData for main class: " << mergedInputClassName << endl;
00683 }
00684
00685 } else {
00686
00687 if( mergedMetaDataDescr.find( mergedInputClassName ) == mergedMetaDataDescr.end( )) {
00688 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > emptyVector;
00689 mergedMetaDataDescr[ mergedInputClassName ] = emptyVector;
00690 }
00691 mergedMetaDataDescr[ mergedInputClassName ].push_back( CdbBdb2RooPayloadMetaDataDescriptor( mergedOriginId,
00692 mergedConditionId,
00693 mergedIsPartitionable,
00694 mergedPartitionId,
00695 mergedClusterId,
00696 mergedIncrementId ));
00697 }
00698
00699 } else {
00700
00701 cerr << errorStr << endl
00702 << " Too few MetaData-s in a block of merged ones." << endl
00703 << " There must be at least 2 of them." << endl;
00704
00705 parserState = PARSER_FAILED;
00706
00707 break;
00708 }
00709
00710 parserState = PARSER_REGULAR;
00711
00712 } else {
00713
00714 parserState = PARSER_FAILED;
00715
00716 break;
00717 }
00718
00719 } else if( "#MERGE" == currentLine ) {
00720
00721 if(( PARSER_IDLE == parserState ) || ( PARSER_REGULAR == parserState ) || ( PARSER_MERGING_BEGIN == parserState )) {
00722
00723 parserState = PARSER_MERGING_BEGIN;
00724
00725 } else if( PARSER_MERGING == parserState ) {
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737 if( mergedConditionId.size( ) > 1 ) {
00738
00739
00740
00741
00742 CdbCPtr<CdbRooConverterBase> converterPtr =
00743 mergingConvertersDict( )->findByInputClassName( mergedInputClassName );
00744
00745 if( converterPtr.isNull( )) {
00746
00747 if( verboseModeFlag ) {
00748 cout << "skipping merged block of MetaData for main class: " << mergedInputClassName << endl;
00749 }
00750
00751 } else {
00752
00753 if( mergedMetaDataDescr.find( mergedInputClassName ) == mergedMetaDataDescr.end( )) {
00754 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > emptyVector;
00755 mergedMetaDataDescr[ mergedInputClassName ] = emptyVector;
00756 }
00757 mergedMetaDataDescr[ mergedInputClassName ].push_back( CdbBdb2RooPayloadMetaDataDescriptor( mergedOriginId,
00758 mergedConditionId,
00759 mergedIsPartitionable,
00760 mergedPartitionId,
00761 mergedClusterId,
00762 mergedIncrementId ));
00763 }
00764
00765 } else {
00766
00767 cerr << errorStr << endl
00768 << " Too few MetaData-s in a block of merged ones." << endl
00769 << " There must be at least 2 of them." << endl;
00770
00771 parserState = PARSER_FAILED;
00772
00773 break;
00774 }
00775
00776 parserState = PARSER_MERGING_BEGIN;
00777
00778 } else {
00779
00780 parserState = PARSER_FAILED;
00781
00782 break;
00783 }
00784
00785 } else if( "#END" == currentLine ) {
00786
00787 if( PARSER_MERGING == parserState ) {
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 if( mergedConditionId.size( ) > 1 ) {
00802
00803
00804
00805
00806 CdbCPtr<CdbRooConverterBase> converterPtr =
00807 mergingConvertersDict( )->findByInputClassName( mergedInputClassName );
00808
00809 if( converterPtr.isNull( )) {
00810
00811 if( verboseModeFlag ) {
00812 cout << "skipping merged block of MetaData for main class: " << mergedInputClassName << endl;
00813 }
00814
00815 } else {
00816
00817 if( mergedMetaDataDescr.find( mergedInputClassName ) == mergedMetaDataDescr.end( )) {
00818 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > emptyVector;
00819 mergedMetaDataDescr[ mergedInputClassName ] = emptyVector;
00820 }
00821 mergedMetaDataDescr[ mergedInputClassName ].push_back( CdbBdb2RooPayloadMetaDataDescriptor( mergedOriginId,
00822 mergedConditionId,
00823 mergedIsPartitionable,
00824 mergedPartitionId,
00825 mergedClusterId,
00826 mergedIncrementId ));
00827 }
00828
00829 } else {
00830
00831 cerr << errorStr << endl
00832 << " Too few MetaData-s in a block of merged ones." << endl
00833 << " There must be at least 2 of them." << endl;
00834
00835 parserState = PARSER_FAILED;
00836
00837 break;
00838 }
00839 }
00840
00841 parserState = PARSER_IDLE;
00842
00843 break;
00844
00845 } else {
00846
00847
00848
00849 UShort_t originId = 0;
00850 UShort_t conditionId = 0;
00851 bool isPartitionable = false;
00852 UShort_t partitionId = 0;
00853 UShort_t clusterId = 0;
00854 UShort_t incrementId = 0;
00855 std::string inputClassName = "";
00856
00857 if( !::translateNextLine( currentLine,
00858 databasePtr,
00859 originId,
00860 conditionId,
00861 isPartitionable,
00862 partitionId,
00863 clusterId,
00864 incrementId,
00865 inputClassName )) {
00866
00867 parserState = PARSER_FAILED;
00868
00869 break;
00870 }
00871
00872 if( PARSER_REGULAR == parserState ) {
00873
00874
00875
00876
00877 CdbCPtr<CdbRooConverterBase> converterPtr =
00878 regularConvertersDict( )->findByInputClassName( inputClassName );
00879
00880 if( converterPtr.isNull( )) {
00881
00882 if( verboseModeFlag ) {
00883 cout << "no converter found for the input class \"" << inputClassName << "\", skipping line " << currentLine<< endl;
00884 }
00885
00886 } else {
00887
00888 if( regularMetaDataDescr.find( inputClassName ) == regularMetaDataDescr.end( )) {
00889 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > emptyVector;
00890 regularMetaDataDescr[ inputClassName ] = emptyVector;
00891 }
00892 regularMetaDataDescr[ inputClassName ].push_back( CdbBdb2RooPayloadMetaDataDescriptor( originId,
00893 conditionId,
00894 isPartitionable,
00895 partitionId,
00896 clusterId,
00897 incrementId ));
00898 }
00899
00900 } else if( PARSER_MERGING_BEGIN == parserState ) {
00901
00902
00903
00904
00905 mergedOriginId = originId;
00906
00907 mergedConditionId.resize( 0 );
00908 mergedConditionId.push_back( conditionId );
00909
00910 mergedIsPartitionable = isPartitionable;
00911 mergedPartitionId = partitionId;
00912 mergedClusterId = clusterId;
00913 mergedIncrementId = incrementId;
00914 mergedInputClassName = inputClassName;
00915
00916 parserState = PARSER_MERGING;
00917
00918 } else if( PARSER_MERGING == parserState ) {
00919
00920
00921
00922
00923 if(( mergedOriginId != originId ) ||
00924 ( mergedIsPartitionable != isPartitionable ) ||
00925 ( mergedPartitionId != partitionId ) ||
00926 ( mergedClusterId != clusterId ) ||
00927 ( mergedIncrementId != incrementId )) {
00928
00929 cerr << errorStr << endl
00930 << " Inconsistent MetaData in a block of merged ones." << endl;
00931
00932 parserState = PARSER_FAILED;
00933
00934 break;
00935 }
00936
00937 mergedConditionId.push_back( conditionId );
00938
00939 } else {
00940
00941 parserState = PARSER_FAILED;
00942
00943 break;
00944 }
00945 }
00946 }
00947 if( PARSER_IDLE != parserState ) {
00948
00949 if( PARSER_FAILED == parserState ) {
00950
00951 cerr << errorStr << endl
00952 << " Incorrect syntax of the definition file:" << endl
00953 << " \"" << theDefinitionFile << "\"" << endl
00954 << " at line #" << currentLineNumber << " containing:" << endl
00955 << " \"" << currentLine << "\"" << endl
00956 << endl;
00957
00958 } else {
00959
00960 cerr << errorStr << endl
00961 << " Incorrect syntax at the end of the definition file:" << endl
00962 << " \"" << theDefinitionFile << "\"" << endl
00963 << " after line #" << currentLineNumber << " containing:" << endl
00964 << " \"" << currentLine << "\"" << endl
00965 << " Perhaps the #END command line is missing?" << endl
00966 << endl;
00967 }
00968 return CdbStatus::Error;
00969 }
00970
00971
00972
00973 for( DescriptorsOfAcceptedMetaData::const_iterator itr = regularMetaDataDescr.begin( );
00974 itr != regularMetaDataDescr.end( );
00975 ++itr ) {
00976
00977 if( verboseModeFlag )
00978 cout << "processing regular InputClass \"" << (*itr).first << "\"" << endl;
00979
00980 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > vectorOfDescriptors = (*itr).second;
00981
00982 unsigned int num = vectorOfDescriptors.size( );
00983 assert( 0 != num );
00984
00985 for( unsigned int i = 0; i < num; ++i ) {
00986
00987 CdbBdb2RooPayloadMetaDataDescriptor descriptor = vectorOfDescriptors[i];
00988
00989 if( verboseModeFlag )
00990 cout << " processing regular MetaData " << descriptor.toString( ) << endl;
00991
00992 if( CdbStatus::Success != ( result = convertMetadata( descriptor.originId,
00993 descriptor.conditionId[0],
00994 descriptor.isPartitionable,
00995 descriptor.partitionId,
00996 descriptor.clusterId,
00997 descriptor.incrementId ))) {
00998 cerr << errorStr << endl
00999 << " Failed when regular processing MetaData " << descriptor.toString( ) << endl;
01000 return result;
01001 }
01002 }
01003 }
01004
01005
01006
01007 for( DescriptorsOfAcceptedMetaData::const_iterator itr = mergedMetaDataDescr.begin( );
01008 itr != mergedMetaDataDescr.end( );
01009 ++itr ) {
01010
01011 if( verboseModeFlag )
01012 cout << "processing merged InputClass \"" << (*itr).first << "\"" << endl;
01013
01014 std::vector< CdbBdb2RooPayloadMetaDataDescriptor > vectorOfDescriptors = (*itr).second;
01015
01016 unsigned int num = vectorOfDescriptors.size( );
01017 assert( 0 != num );
01018
01019 for( unsigned int i = 0; i < num; ++i ) {
01020
01021 CdbBdb2RooPayloadMetaDataDescriptor descriptor = vectorOfDescriptors[i];
01022
01023 if( verboseModeFlag )
01024 cout << " processing merged MetaData " << descriptor.toString( ) << endl;
01025
01026 if( CdbStatus::Success != ( result = convertMetadata( descriptor.originId,
01027 descriptor.conditionId,
01028 descriptor.isPartitionable,
01029 descriptor.partitionId,
01030 descriptor.clusterId,
01031 descriptor.incrementId ))) {
01032 cerr << errorStr << endl
01033 << " Failed when processing merged MetaData " << descriptor.toString( ) << endl;
01034 return result;
01035 }
01036 }
01037 }
01038 return CdbStatus::Success;
01039 }
01040
01041 CdbStatus
01042 CdbBdb2RooPayloadConversionFwk::convertMetadata( UShort_t theOriginId,
01043 UShort_t theConditionId,
01044 bool isPartitionableFlag,
01045 UShort_t thePartitionId,
01046 UShort_t theClusterId,
01047 UShort_t theIncrementId )
01048 {
01049 const char* errorStr = "CdbBdb2RooPayloadConversionFwk::::convertMetadata(regular) - ERROR.";
01050
01051 if( verboseModeFlag ) {
01052 cout << "CdbBdb2RooPayloadConversionFwk::convertMetadata(regular) : PARAMETERS OF THE METHOD {" << endl
01053 << " theOriginId = " << theOriginId << endl
01054 << " theConditionId = " << theConditionId << endl
01055 << " isPartitionableFlag = " << isPartitionableFlag << endl
01056 << " thePartitionId = " << thePartitionId << endl
01057 << " theClusterId = " << theClusterId << endl
01058 << " theIncrementId = " << theIncrementId << endl
01059 << "}" << endl;
01060 }
01061
01062 CdbStatus result = CdbStatus::Error;
01063
01064
01065
01066 CdbCPtr< CdbRooRoMetaDataR > mdPtr;
01067 if( CdbStatus::Success != ( result = CdbRooRoFileUtils::instance( ).findMetaData( mdPtr,
01068 theConditionId,
01069 isPartitionableFlag,
01070 thePartitionId,
01071 theClusterId,
01072 theIncrementId,
01073 theOriginId ))) {
01074 cerr << errorStr << endl
01075 << " Failed to locate the input MetaData object." << endl;
01076 return result;
01077 }
01078 CdbCPtr< CdbRooRoOiCollectionR> oiCollectionPtr = mdPtr->originalIntervalsCollection( );
01079
01080 if( debugModeFlag ) {
01081 cout << "CdbBdb2RooPayloadConversionFwk::convertMetadata(regular) : DUMP OF THE ORIGINAL COLLECTION {" << endl;
01082 oiCollectionPtr->dump( cout );
01083 }
01084
01085
01086
01087 CdbCPtr< TFile > databasePtr;
01088 if( CdbStatus::Success != ( result = CdbRooRoFileUtils::instance( ).findObjectsDatabase( databasePtr,
01089 isPartitionableFlag,
01090 thePartitionId,
01091 theClusterId,
01092 theIncrementId,
01093 theOriginId,
01094 "update" ))) {
01095 cerr << errorStr << endl
01096 << " Failed to locate the file for output objects." << endl;
01097 return result;
01098 }
01099 if( doNotCompressModeFlag ) databasePtr->SetCompressionLevel( 0 );
01100
01101
01102
01103
01104
01105
01106
01107 const std::string treeNameBase =
01108 CdbRooRoFileUtils::nameOfObjectsContainer( theConditionId,
01109 isPartitionableFlag,
01110 thePartitionId,
01111 theClusterId,
01112 theIncrementId,
01113 theOriginId ) + ".";
01114
01115
01116
01117 std::map< UShort_t, CdbBdb2RooPayloadContainerContext* > executionPlan;
01118
01119
01120
01121 std::map< std::string, bool > mapOfProcessedObjects;
01122
01123
01124
01125 if( debugModeFlag )
01126 cout << endl
01127 << "Conversion pass I: preparing an execution plan..." << endl
01128 << endl;
01129
01130 UInt_t nIntervals = oiCollectionPtr->size( );
01131 assert( nIntervals > 0 );
01132
01133 for( UInt_t idx = 1; idx < nIntervals; ++idx ) {
01134
01135 CdbRooRoOiR oi;
01136
01137 BdbTime beginOfDuration;
01138 BdbTime endOfDuration;
01139
01140 if( CdbStatus::Success != ( result = oiCollectionPtr->find( idx,
01141 oi,
01142 beginOfDuration,
01143 endOfDuration ))) {
01144 cerr << errorStr << endl
01145 << " Failed to find an 'origina' interval with index = " << idx << endl;
01146 return result;
01147 }
01148
01149 if( debugModeFlag )
01150 cout << " " << oi.object( ) << " <-- " << oi.legacyObjectAddress( ) << endl;
01151
01152
01153
01154
01155 if( ( oi.object( ).origin ( ) != theOriginId ) ||
01156 ( oi.object( ).condition( ) != theConditionId ) ||
01157 ( oi.object( ).cluster ( ) != theClusterId ) ||
01158 ( oi.object( ).partition( ) != thePartitionId ) ||
01159 ( oi.object( ).increment( ) != theIncrementId )) {
01160
01161 cerr << errorStr << endl
01162 << " The output object address " << oi.object( ) << " doesn't match" << endl
01163 << " the location of the output container." << endl;
01164 return CdbStatus::Error;
01165 }
01166
01167
01168
01169 if( mapOfProcessedObjects.find( oi.object( ).toString( )) != mapOfProcessedObjects.end( )) continue;
01170
01171 mapOfProcessedObjects[oi.object( ).toString( )] = true;
01172
01173
01174
01175 BdbRef(BdbObject) legacyObjectRef;
01176
01177 if( !translate_OID( legacyObjectRef,
01178 oi.legacyObjectAddress( ))) {
01179 cerr << errorStr << endl
01180 << " Failed to translate the OID of the legacy object: " << oi.legacyObjectAddress( ) << endl;
01181 return CdbStatus::Error;
01182 }
01183
01184
01185
01186
01187 const std::string legacyObjectTypeName = legacyObjectRef.typeName( );
01188 {
01189 if( !CdbBdbSchemaUtils::instance( ).isA( legacyObjectRef.typeN( ),
01190 ooTypeN( BdbObject ))) {
01191 cerr << errorStr << endl
01192 << " The legacy object doesn't derive from BdbObject: " << oi.legacyObjectAddress( ) << endl;
01193 return CdbStatus::Error;
01194 }
01195 }
01196
01197
01198
01199
01200
01201
01202
01203 if( executionPlan.find( oi.object( ).container( )) == executionPlan.end( )) {
01204
01205
01206
01207 const std::string treeName = treeNameBase + CdbStringUtils::toString( oi.object( ).container( ));
01208
01209
01210
01211 CdbCPtr< CdbRooConverterBase > converterPtr = regularConvertersDict( )->findByInputClassName( legacyObjectTypeName );
01212 if( converterPtr.isNull( )) {
01213 cerr << errorStr << endl
01214 << " No converter avaialble for the legacy class: " << legacyObjectTypeName << endl;
01215 return CdbStatus::Error;
01216 }
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 databasePtr->Cd( "" );
01227 gDirectory->Cd( databasePtr->GetPath( ));
01228
01229
01230
01231
01232 executionPlan[oi.object( ).container( )] = new CdbBdb2RooPayloadContainerContext( treeName,
01233 "A tree for 'payload' objects" ,
01234 converterPtr );
01235 }
01236 executionPlan[oi.object( ).container( )]->add( legacyObjectRef,
01237 oi.object( ));
01238 }
01239
01240 if( debugModeFlag )
01241 cout << endl
01242 << "Conversion pass II: performing the actual conversion..." << endl
01243 << endl;
01244
01245 for( std::map< UShort_t, CdbBdb2RooPayloadContainerContext* >::iterator itr = executionPlan.begin( );
01246 itr != executionPlan.end( );
01247 ++itr ) {
01248
01249 CdbBdb2RooPayloadContainerContext* containerContext = (*itr).second;
01250
01251
01252
01253
01254
01255
01256
01257 const char* branchName = "0";
01258
01259 TBranch* branch = containerContext->converterPtr->branchConstructor( containerContext->tree,
01260 branchName );
01261
01262 UInt_t nIntervals = containerContext->inObjects.size( );
01263 assert( nIntervals > 0 );
01264
01265 for( UInt_t idx = 0; idx < nIntervals; ++idx ) {
01266
01267 BdbRef(BdbObject)& legacyObjectRef = containerContext->inObjects [idx];
01268 CdbRooRoObjectIdR& outputObjectId = containerContext->outObjects[idx];
01269
01270 if( debugModeFlag )
01271 cout << " " << outputObjectId << " <-- " << legacyObjectRef.sprint( ) << " : \"" << containerContext->converterPtr->inputClassName( ) << "\"" << endl;
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 {
01284 std::vector< BdbRef(BdbObject) > extraObjects( 0 );
01285
01286 if( CdbStatus::Success != ( result = containerContext->converterPtr->conversion( legacyObjectRef,
01287 extraObjects ))) {
01288 cerr << errorStr << endl
01289 << " Failed to convert the legacy object " << legacyObjectRef.sprint( ) << endl;
01290 return result;
01291 }
01292
01293
01294
01295 containerContext->tree.Fill( );
01296
01297
01298
01299
01300 if( debugModeFlag )
01301 cout << " tree->GetNbranches( ) = " << containerContext->tree.GetNbranches( ) << endl
01302 << " tree->GetEntries ( ) = " << containerContext->tree.GetEntries( ) << endl
01303 << "branch->GetEntries ( ) = " << branch->GetEntries( ) << endl;
01304
01305 Long64_t objectIndexInBranch = branch->GetEntries( ) - 1;
01306
01307 if(( objectIndexInBranch < 0 ) ||
01308 ( objectIndexInBranch >= 0xFFFF ) ||
01309 ( objectIndexInBranch != outputObjectId.index( ))) {
01310
01311 cerr << errorStr << endl
01312 << " The just converted object " << outputObjectId << " produced from the legacy object " << legacyObjectRef.sprint( ) << endl
01313 << " was writtent into a branch with a noon-valid index " << objectIndexInBranch << endl;
01314
01315 return CdbStatus::Error;
01316 }
01317 }
01318 }
01319
01320
01321
01322 databasePtr->Cd( "" );
01323 gDirectory->Cd( databasePtr->GetPath( ));
01324
01325 Int_t numBytesWritten = databasePtr->WriteObject( &containerContext->tree,
01326 containerContext->tree.GetName( ));
01327 if( numBytesWritten <= 0 ) {
01328 cerr << errorStr << endl
01329 << " Failed to save the tree \"" << containerContext->tree.GetName( ) << "\" in the file: " << databasePtr->GetName( ) << endl;
01330 return CdbStatus::Error;
01331 }
01332 if( debugModeFlag )
01333 cout << endl
01334 << "Total of " << nIntervals << " converted and stored into the tree \"" << containerContext->tree.GetName( ) << "\"." << endl
01335 << endl;
01336
01337
01338
01339 delete containerContext;
01340 }
01341 return CdbStatus::Success;
01342 }
01343
01344 CdbStatus
01345 CdbBdb2RooPayloadConversionFwk::convertMetadata( UShort_t theOriginId,
01346 const std::vector<UShort_t>& theConditionId,
01347 bool isPartitionableFlag,
01348 UShort_t thePartitionId,
01349 UShort_t theClusterId,
01350 UShort_t theIncrementId )
01351 {
01352 const char* infoStr = "CdbBdb2RooPayloadConversionFwk::::convertMetadata(merging) - INFO.";
01353 const char* errorStr = "CdbBdb2RooPayloadConversionFwk::::convertMetadata(merging) - ERROR.";
01354
01355 CdbStatus result = CdbStatus::Error;
01356
01357 if( debugModeFlag ) {
01358 cout << infoStr << endl
01359 << " Converting and merging the following conditions:" << endl
01360 << endl
01361 << " Origin identifier : " << theOriginId << endl
01362 << " Condition identifiers : " << ::vector2string( theConditionId ) << endl
01363 << " Is partitionable : " << ( isPartitionableFlag ? "Yes" : "No" ) << endl
01364 << " Partition identifier : " << thePartitionId << endl
01365 << " Cluster identifier : " << theClusterId << endl
01366 << " Increment number : " << theIncrementId << endl
01367 << endl;
01368 }
01369
01370
01371
01372 const unsigned int nConditions = theConditionId.size( );
01373 if( nConditions < 2 ) {
01374 cerr << errorStr << endl
01375 << " The total number of conditions to be merged is less than 2." << endl;
01376 return CdbStatus::IllegalParameters;
01377 }
01378
01379
01380
01381
01382
01383
01384 std::vector< CdbCPtr< CdbRooRoOiCollectionR> > oiCollectionPtr( nConditions );
01385
01386 for( unsigned int conditionIdx = 0; conditionIdx < nConditions; ++conditionIdx ) {
01387
01388 CdbCPtr< CdbRooRoMetaDataR > mdPtr;
01389 if( CdbStatus::Success != ( result = CdbRooRoFileUtils::instance( ).findMetaData( mdPtr,
01390 theConditionId[conditionIdx],
01391 isPartitionableFlag,
01392 thePartitionId,
01393 theClusterId,
01394 theIncrementId,
01395 theOriginId ))) {
01396 cerr << errorStr << endl
01397 << " Failed to locate the input MetaData object for:" << endl;
01398
01399 ::printMetDataParameters( theOriginId,
01400 theConditionId[conditionIdx],
01401 isPartitionableFlag,
01402 thePartitionId,
01403 theClusterId,
01404 theIncrementId );
01405 return result;
01406 }
01407 oiCollectionPtr[conditionIdx] = mdPtr->originalIntervalsCollection( );
01408 }
01409
01410 for( unsigned int conditionIdx = 1; conditionIdx < nConditions; ++conditionIdx ) {
01411 if( oiCollectionPtr[0]->size( ) != oiCollectionPtr[conditionIdx]->size( )) {
01412 cerr << errorStr << endl
01413 << " MetData objects passed to the current procedure do not have the same" << endl
01414 << " number of original intervals. Merging is not possible for these conditions." << endl;
01415 return CdbStatus::Error;
01416 }
01417 }
01418
01419
01420
01421
01422
01423 CdbCPtr< TFile > databasePtr;
01424 if( CdbStatus::Success != ( result = CdbRooRoFileUtils::instance( ).findObjectsDatabase( databasePtr,
01425 isPartitionableFlag,
01426 thePartitionId,
01427 theClusterId,
01428 theIncrementId,
01429 theOriginId,
01430 "update" ))) {
01431 cerr << errorStr << endl
01432 << " Failed to create/reopen a file for output objects." << endl;
01433 return result;
01434 }
01435 if( doNotCompressModeFlag ) databasePtr->SetCompressionLevel( 0 );
01436
01437
01438
01439
01440
01441
01442
01443 std::vector< std::string > treeNameBase( nConditions );
01444 for( unsigned int conditionIdx = 0; conditionIdx < nConditions; ++conditionIdx ) {
01445
01446 treeNameBase[conditionIdx] =
01447 CdbRooRoFileUtils::nameOfObjectsContainer( theConditionId[conditionIdx],
01448 isPartitionableFlag,
01449 thePartitionId,
01450 theClusterId,
01451 theIncrementId,
01452 theOriginId ) + ".";
01453 }
01454
01455
01456
01457
01458
01459
01460 std::map< UShort_t, CdbBdb2RooPayloadMainContainerContext* > mainExecutionPlan;
01461
01462 std::vector< std::map< UShort_t, CdbBdb2RooPayloadExtraContainerContext* > > executionPlan( nConditions );
01463
01464
01465
01466
01467
01468
01469
01470
01471 std::map< std::string, bool > mapOfProcessedObjects;
01472
01473
01474
01475 if( debugModeFlag )
01476 cout << endl
01477 << "Conversion pass I: preparing an execution plan..." << endl
01478 << endl;
01479
01480 const UInt_t nIntervals = oiCollectionPtr[0]->size( );
01481
01482 assert( nIntervals > 0 );
01483
01484 if( debugModeFlag )
01485 cout << "There are " << nIntervals - 1 << " intervals to be converted and merged." << endl;
01486
01487 for( UInt_t idx = 1; idx < nIntervals; ++idx ) {
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497 std::vector< CdbRooRoOiR > oi( nConditions );
01498
01499
01500
01501 std::vector< BdbRef(BdbObject) > legacyObjectRef( nConditions );
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511 for( int conditionIdx = nConditions - 1; conditionIdx >= 0; --conditionIdx ) {
01512
01513 BdbTime beginOfDuration;
01514 BdbTime endOfDuration;
01515
01516 if( CdbStatus::Success != ( result = oiCollectionPtr[conditionIdx]->find( idx,
01517 oi[conditionIdx],
01518 beginOfDuration,
01519 endOfDuration ))) {
01520 cerr << errorStr << endl
01521 << " Failed to find an 'origina' interval with index = " << idx << endl;
01522 return result;
01523 }
01524
01525 if( debugModeFlag )
01526 cout << "[" << conditionIdx << "]" << " " << oi[conditionIdx].object( ) << " <-- " << oi[conditionIdx].legacyObjectAddress( ) << endl;
01527
01528
01529
01530
01531 if( ( oi[conditionIdx].object( ).origin ( ) != theOriginId ) ||
01532 ( oi[conditionIdx].object( ).condition( ) != theConditionId[conditionIdx] ) ||
01533 ( oi[conditionIdx].object( ).cluster ( ) != theClusterId ) ||
01534 ( oi[conditionIdx].object( ).partition( ) != thePartitionId ) ||
01535 ( oi[conditionIdx].object( ).increment( ) != theIncrementId )) {
01536
01537 cerr << errorStr << endl
01538 << " The output object address " << oi[conditionIdx].object( ) << " doesn't match" << endl
01539 << " the location of the output container." << endl;
01540 return CdbStatus::Error;
01541 }
01542
01543
01544
01545
01546 if( 0 == conditionIdx ) {
01547
01548 if( mapOfProcessedObjects.find( oi[conditionIdx].object( ).toString( )) != mapOfProcessedObjects.end( )) {
01549
01550 cerr << errorStr << endl
01551 << " An attempt to merge conditions with duplicate objects in the main" << endl
01552 << " condition has been detected. Aborting the operation." << endl;
01553
01554 ::printMetDataParameters( theOriginId,
01555 theConditionId[conditionIdx],
01556 isPartitionableFlag,
01557 thePartitionId,
01558 theClusterId,
01559 theIncrementId );
01560
01561 return CdbStatus::Error;
01562 }
01563 }
01564 mapOfProcessedObjects[oi[conditionIdx].object( ).toString( )] = true;
01565
01566
01567
01568 if( !translate_OID( legacyObjectRef[conditionIdx],
01569 oi[conditionIdx].legacyObjectAddress( ))) {
01570 cerr << errorStr << endl
01571 << " Failed to translate the OID of the legacy object: " << oi[conditionIdx].legacyObjectAddress( ) << endl;
01572 return CdbStatus::Error;
01573 }
01574
01575
01576
01577
01578 const std::string legacyObjectTypeName = legacyObjectRef[conditionIdx].typeName( );
01579 {
01580 if( !CdbBdbSchemaUtils::instance( ).isA( legacyObjectRef[conditionIdx].typeN( ),
01581 ooTypeN( BdbObject ))) {
01582 cerr << errorStr << endl
01583 << " The legacy object doesn't derive from BdbObject: " << oi[conditionIdx].legacyObjectAddress( ) << endl;
01584 return CdbStatus::Error;
01585 }
01586 }
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 if( 0 == conditionIdx ) {
01600
01601 if( mainExecutionPlan.find( oi[conditionIdx].object( ).container( )) == mainExecutionPlan.end( )) {
01602
01603
01604
01605 const std::string treeName = treeNameBase[conditionIdx] + CdbStringUtils::toString( oi[conditionIdx].object( ).container( ));
01606
01607
01608
01609 CdbCPtr< CdbRooConverterBase > converterPtr = mergingConvertersDict( )->findByInputClassName( legacyObjectTypeName );
01610 if( converterPtr.isNull( )) {
01611 cerr << errorStr << endl
01612 << " No MERGING converter avaialble for the legacy class: " << legacyObjectTypeName << endl;
01613 return CdbStatus::Error;
01614 }
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 databasePtr->Cd( "" );
01625 gDirectory->Cd( databasePtr->GetPath( ));
01626
01627
01628
01629
01630 mainExecutionPlan[oi[conditionIdx].object( ).container( )] = new CdbBdb2RooPayloadMainContainerContext( treeName,
01631 "A tree for 'payload' objects" ,
01632 converterPtr );
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 mainExecutionPlan[oi[conditionIdx].object( ).container( )]->add( legacyObjectRef,
01646 oi[conditionIdx].object( ));
01647
01648 for( unsigned int extraConditionIdx = 1; extraConditionIdx < nConditions; ++extraConditionIdx ) {
01649
01650 const unsigned int containerId = oi[extraConditionIdx].object( ).container( );
01651
01652 executionPlan[extraConditionIdx][containerId]->add( legacyObjectRef[extraConditionIdx],
01653 oi[extraConditionIdx].object( ),
01654 oi[conditionIdx].object( ));
01655 }
01656
01657 } else {
01658
01659
01660
01661
01662
01663
01664 if( executionPlan[conditionIdx].find( oi[conditionIdx].object( ).container( )) == executionPlan[conditionIdx].end( )) {
01665
01666
01667
01668 const std::string treeName = treeNameBase[conditionIdx] + CdbStringUtils::toString( oi[conditionIdx].object( ).container( ));
01669
01670
01671
01672
01673 CdbCPtr< CdbRooConverterBase > converterPtr;
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 databasePtr->Cd( "" );
01684 gDirectory->Cd( databasePtr->GetPath( ));
01685
01686
01687
01688
01689 executionPlan[conditionIdx][oi[conditionIdx].object( ).container( )] = new CdbBdb2RooPayloadExtraContainerContext( treeName,
01690 "A tree for 'payload' objects" ,
01691 converterPtr );
01692 }
01693
01694
01695
01696
01697
01698
01699 }
01700 }
01701
01702
01703
01704 for( unsigned int conditionIdx = 1; conditionIdx < nConditions; ++conditionIdx ) {
01705
01706
01707
01708 if( oi[0].begin( ) != oi[conditionIdx].begin( )) {
01709 cerr << errorStr << endl
01710 << " Checked the begin validity time of objects in merged conditions and found" << endl
01711 << " that an attempt to merge asynchronious conditions is taking place." << endl;
01712 return CdbStatus::Error;
01713 }
01714 if( oi[0].end( ) != oi[conditionIdx].end( )) {
01715 cerr << errorStr << endl
01716 << " Checked the begin validity time of objects in merged conditions and found" << endl
01717 << " that an attempt to merge asynchronious conditions is taking place." << endl;
01718 return CdbStatus::Error;
01719 }
01720 }
01721 }
01722
01723 if( debugModeFlag )
01724 cout << endl
01725 << "Conversion pass II: performing the actual conversion..." << endl
01726 << endl;
01727
01728
01729
01730 for( std::map< UShort_t, CdbBdb2RooPayloadMainContainerContext* >::iterator itr = mainExecutionPlan.begin( );
01731 itr != mainExecutionPlan.end( );
01732 ++itr ) {
01733
01734 CdbBdb2RooPayloadMainContainerContext* containerContext = (*itr).second;
01735
01736
01737
01738
01739
01740
01741
01742 const char* branchName = "0";
01743
01744 TBranch* branch = containerContext->converterPtr->branchConstructor( containerContext->tree,
01745 branchName );
01746
01747 UInt_t nIntervals = containerContext->inObjects.size( );
01748 assert( nIntervals > 0 );
01749
01750 for( UInt_t idx = 0; idx < nIntervals; ++idx ) {
01751
01752 BdbRef(BdbObject) mainLegacyObjectRef = containerContext->inObjects[idx][0];
01753
01754
01755
01756
01757 std::vector< BdbRef(BdbObject) >::iterator beginItr = containerContext->inObjects[idx].begin( );
01758 ++beginItr;
01759 std::vector< BdbRef(BdbObject) >::iterator endItr = containerContext->inObjects[idx].end( );
01760
01761 std::vector< BdbRef(BdbObject) > extraLegacyObjectRef( beginItr, endItr);
01762
01763 CdbRooRoObjectIdR outputObjectId = containerContext->outObjects[idx];
01764
01765 if( debugModeFlag )
01766 cout << " " << outputObjectId << " <-- " << mainLegacyObjectRef.sprint( ) << " : \"" << containerContext->converterPtr->inputClassName( ) << "\"" << endl;
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778 {
01779 if( CdbStatus::Success != ( result = containerContext->converterPtr->conversion( mainLegacyObjectRef,
01780 extraLegacyObjectRef ))) {
01781 cerr << errorStr << endl
01782 << " Failed to convert the main legacy object " << mainLegacyObjectRef.sprint( ) << endl;
01783 return result;
01784 }
01785
01786
01787
01788 containerContext->tree.Fill( );
01789
01790
01791
01792
01793 if( debugModeFlag )
01794 cout << " tree->GetNbranches( ) = " << containerContext->tree.GetNbranches( ) << endl
01795 << " tree->GetEntries ( ) = " << containerContext->tree.GetEntries( ) << endl
01796 << "branch->GetEntries ( ) = " << branch->GetEntries( ) << endl;
01797
01798 Long64_t objectIndexInBranch = branch->GetEntries( ) - 1;
01799
01800 if(( objectIndexInBranch < 0 ) ||
01801 ( objectIndexInBranch >= 0xFFFF ) ||
01802 ( objectIndexInBranch != outputObjectId.index( ))) {
01803
01804 cerr << errorStr << endl
01805 << " The just converted object " << outputObjectId << " produced from the legacy object " << mainLegacyObjectRef.sprint( ) << endl
01806 << " was writtent into a branch with a noon-valid index " << objectIndexInBranch << endl;
01807
01808 return CdbStatus::Error;
01809 }
01810 }
01811 }
01812
01813
01814
01815 databasePtr->Cd( "" );
01816 gDirectory->Cd( databasePtr->GetPath( ));
01817
01818 Int_t numBytesWritten = databasePtr->WriteObject( &containerContext->tree,
01819 containerContext->tree.GetName( ));
01820 if( numBytesWritten <= 0 ) {
01821 cerr << errorStr << endl
01822 << " Failed to save the tree \"" << containerContext->tree.GetName( ) << "\" in the file: " << databasePtr->GetName( ) << endl;
01823 return CdbStatus::Error;
01824 }
01825 if( debugModeFlag )
01826 cout << endl
01827 << "Total of " << nIntervals << " converted and stored into the tree \"" << containerContext->tree.GetName( ) << "\"." << endl
01828 << endl;
01829
01830
01831
01832 delete containerContext;
01833 }
01834
01835
01836
01837 for( unsigned int conditionIdx = 1; conditionIdx < nConditions; ++conditionIdx ) {
01838
01839 for( std::map< UShort_t, CdbBdb2RooPayloadExtraContainerContext* >::iterator itr = executionPlan[conditionIdx].begin( );
01840 itr != executionPlan[conditionIdx].end( );
01841 ++itr ) {
01842
01843 CdbBdb2RooPayloadExtraContainerContext* containerContext = (*itr).second;
01844
01845
01846
01847 const char* branchName = "0";
01848
01849 CdbRooObjectHasMovedR* dummyObjectPtr = 0;
01850
01851 TBranch* branch = containerContext->tree.Branch( branchName,
01852 "CdbRooObjectHasMovedR",
01853 &dummyObjectPtr );
01854
01855 UInt_t nIntervals = containerContext->inObjects.size( );
01856 assert( nIntervals > 0 );
01857
01858 for( UInt_t idx = 0; idx < nIntervals; ++idx ) {
01859
01860 BdbRef(BdbObject)& legacyObjectRef = containerContext->inObjects[idx];
01861 CdbRooRoObjectIdR& outputObjectId = containerContext->outObjects[idx];
01862 CdbRooRoObjectIdR& mainObjectId = containerContext->mainObjects[idx];
01863
01864 if( debugModeFlag )
01865 cout << " " << mainObjectId << " <== " << outputObjectId << " <-- " << legacyObjectRef.sprint( ) << " : \"" << legacyObjectRef.typeName( ) << "\"" << endl;
01866
01867
01868
01869
01870
01871
01872 {
01873 if( 0 != dummyObjectPtr ) delete dummyObjectPtr;
01874 dummyObjectPtr = new CdbRooObjectHasMovedR( mainObjectId.toString( ));
01875
01876
01877
01878 containerContext->tree.Fill( );
01879
01880 if( 0 != dummyObjectPtr ) delete dummyObjectPtr;
01881 dummyObjectPtr = 0;
01882
01883
01884
01885
01886 if( debugModeFlag )
01887 cout << " tree->GetNbranches( ) = " << containerContext->tree.GetNbranches( ) << endl
01888 << " tree->GetEntries ( ) = " << containerContext->tree.GetEntries( ) << endl
01889 << "branch->GetEntries ( ) = " << branch->GetEntries( ) << endl;
01890
01891 Long64_t objectIndexInBranch = branch->GetEntries( ) - 1;
01892
01893 if(( objectIndexInBranch < 0 ) ||
01894 ( objectIndexInBranch >= 0xFFFF ) ||
01895 ( objectIndexInBranch != outputObjectId.index( ))) {
01896
01897 cerr << errorStr << endl
01898 << " The just converted object " << outputObjectId << " produced from the legacy object " << legacyObjectRef.sprint( ) << endl
01899 << " was writtent into a branch with a noon-valid index " << objectIndexInBranch << endl;
01900
01901 return CdbStatus::Error;
01902 }
01903 }
01904 }
01905 if( 0 != dummyObjectPtr ) delete dummyObjectPtr;
01906 dummyObjectPtr = 0;
01907
01908
01909
01910 databasePtr->Cd( "" );
01911 gDirectory->Cd( databasePtr->GetPath( ));
01912
01913 Int_t numBytesWritten = databasePtr->WriteObject( &containerContext->tree,
01914 containerContext->tree.GetName( ));
01915 if( numBytesWritten <= 0 ) {
01916 cerr << errorStr << endl
01917 << " Failed to save the tree \"" << containerContext->tree.GetName( ) << "\" in the file: " << databasePtr->GetName( ) << endl;
01918 return CdbStatus::Error;
01919 }
01920 if( debugModeFlag )
01921 cout << endl
01922 << "Total of " << nIntervals << " converted and stored into the tree \"" << containerContext->tree.GetName( ) << "\"." << endl
01923 << endl;
01924
01925
01926
01927 delete containerContext;
01928 }
01929 }
01930 return CdbStatus::Success;
01931 }
01932
01933 CdbBdb2RooPayloadConvertersDict*
01934 CdbBdb2RooPayloadConversionFwk::regularConvertersDict( )
01935 {
01936 static CdbBdb2RooPayloadConvertersDict myDict;
01937 return &myDict;
01938 }
01939
01940 CdbBdb2RooPayloadConvertersDict*
01941 CdbBdb2RooPayloadConversionFwk::mergingConvertersDict( )
01942 {
01943 static CdbBdb2RooPayloadConvertersDict myDict;
01944 return &myDict;
01945 }
01946
01947
01948
01949