00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CondTools/DT/interface/DTConfigHandler.h"
00014
00015
00016
00017
00018 #include "CondTools/DT/interface/DTDBSession.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 int DTConfigHandler::maxBrickNumber = 50;
00029 int DTConfigHandler::maxStringNumber = 1000;
00030 int DTConfigHandler::maxByteNumber = 1000000;
00031 DTConfigHandler::handler_map DTConfigHandler::handlerMap;
00032
00033
00034
00035
00036 DTConfigHandler::DTConfigHandler( DTDBSession* session,
00037 const std::string& token ):
00038 dbSession( session ),
00039 objToken( token ),
00040 refSet( 0 ),
00041 cachedBrickNumber( 0 ),
00042 cachedStringNumber( 0 ),
00043 cachedByteNumber( 0 ) {
00044 }
00045
00046
00047
00048
00049
00050 DTConfigHandler::~DTConfigHandler() {
00051 purge();
00052 delete refSet;
00053 refSet = 0;
00054 }
00055
00056
00057
00058
00059
00061 DTConfigHandler* DTConfigHandler::create( DTDBSession* session,
00062 const std::string& token ) {
00063
00064 DTConfigHandler* handlerPtr = 0;
00065
00066
00067
00068
00069
00070
00071
00072 c_map_iter iter = handlerMap.find( session );
00073 if ( iter == handlerMap.end() )
00074 handlerMap.insert( std::pair<const DTDBSession*,DTConfigHandler*>(
00075 session,
00076 handlerPtr = new DTConfigHandler( session,
00077 token ) ) );
00078 else handlerPtr = iter->second;
00079 return handlerPtr;
00080
00081 }
00082
00083
00084 void DTConfigHandler::remove( const DTDBSession* session ) {
00085
00086
00087 map_iter iter = handlerMap.find( session );
00088 if ( iter != handlerMap.end() ) {
00089 delete iter->second;
00090 handlerMap.erase( iter );
00091 }
00092 return;
00093 }
00094
00095
00096 void DTConfigHandler::remove( const DTConfigHandler* handler ) {
00097 map_iter iter = handlerMap.begin();
00098 map_iter iend = handlerMap.end();
00099 while ( iter != iend ) {
00100 if ( iter->second == handler ) {
00101 handlerMap.erase( iter );
00102 delete handler;
00103 return;
00104 }
00105 iter++;
00106 }
00107 return;
00108 }
00109
00110
00112 const DTConfigList* DTConfigHandler::getContainer() {
00113 if ( refSet == 0 )
00114 refSet = new cond::TypedRef<DTConfigList>( *dbSession->poolDB(),
00115 objToken );
00116 return refSet->ptr();
00117 }
00118
00119
00120 int DTConfigHandler::get( int cfgId, DTConfigData*& obj ) {
00121
00122 getContainer();
00123 const_iterator iter = refMap.find( cfgId );
00124
00125 if ( iter != refMap.end() ) {
00126 obj = iter->second->ptr();
00127 return 0;
00128 }
00129 else {
00130 DTConfigToken token;
00131 if ( refSet->ptr()->get( cfgId, token ) == 0 ) {
00132 std::string actualToken( token.ref );
00133 int actualId = token.id;
00134 if ( ( actualToken == std::string( "dummyToken" ) ) &&
00135 ( actualId > 0 ) ) {
00136 refSet->ptr()->get( -999999999, token );
00137 actualToken = compToken( token.ref, actualId );
00138 }
00139 if ( ( cachedBrickNumber > maxBrickNumber ) ||
00140 ( cachedStringNumber > maxStringNumber ) ||
00141 ( cachedByteNumber > maxByteNumber ) ) purge();
00142 cond::TypedRef<DTConfigData>* refObj =
00143 new cond::TypedRef<DTConfigData>( *dbSession->poolDB(),
00144 actualToken );
00145 refMap.insert( std::pair<int,cond::TypedRef<DTConfigData>*>(
00146 cfgId, refObj ) );
00147 obj = refObj->ptr();
00148 DTConfigData::data_iterator d_iter = obj->dataBegin();
00149 DTConfigData::data_iterator d_iend = obj->dataEnd();
00150 cachedBrickNumber++;
00151 cachedStringNumber += ( d_iend - d_iter );
00152 while ( d_iter != d_iend ) cachedByteNumber += ( *d_iter++ ).size();
00153
00154 return -1;
00155 }
00156 else {
00157 obj = 0;
00158 return -2;
00159 }
00160 }
00161 return 999;
00162
00163 }
00164
00165
00166 void DTConfigHandler::getData( int cfgId,
00167 std::vector<const std::string*>& list ) {
00168 DTConfigData* obj = 0;
00169 get( cfgId, obj );
00170 if ( obj == 0 ) return;
00171 DTConfigData::data_iterator d_iter = obj->dataBegin();
00172 DTConfigData::data_iterator d_iend = obj->dataEnd();
00173 while ( d_iter != d_iend ) list.push_back( &( *d_iter++ ) );
00174 DTConfigData::link_iterator l_iter = obj->linkBegin();
00175 DTConfigData::link_iterator l_iend = obj->linkEnd();
00176 while ( l_iter != l_iend ) getData( *l_iter++, list );
00177 return;
00178 }
00179
00180
00181 int DTConfigHandler::set( int cfgId, const std::string& token ) {
00182 getContainer();
00183 DTConfigToken configToken;
00184 configToken.id = compToken( token );
00185 configToken.ref = token;
00186 DTConfigList* rs = refSet->ptr();
00187 int status = rs->set( cfgId, configToken );
00188 refSet->markUpdate();
00189 return status;
00190 }
00191
00192
00193 DTConfigHandler::const_iterator DTConfigHandler::begin() const {
00194 return refMap.begin();
00195 }
00196
00197
00198 DTConfigHandler::const_iterator DTConfigHandler::end() const {
00199 return refMap.end();
00200 }
00201
00202 void DTConfigHandler::purge() {
00203 std::cout << "DTConfigHandler::purge "
00204 << this << " " << dbSession << " "
00205 << cachedBrickNumber << " "
00206 << cachedStringNumber << " "
00207 << cachedByteNumber << std::endl;
00208 const_iterator iter = refMap.begin();
00209 const_iterator iend = refMap.end();
00210 while ( iter != iend ) {
00211 delete iter->second;
00212 *iter++;
00213 }
00214 refMap.clear();
00215 cachedBrickNumber = 0;
00216 cachedStringNumber = 0;
00217 cachedByteNumber = 0;
00218 return;
00219 }
00220
00221
00222 std::string DTConfigHandler::clone( DTDBSession* newSession,
00223 const std::string& objContainer,
00224 const std::string& refContainer ) {
00225 const DTConfigList* rs = getContainer();
00226 DTConfigList* rn = new DTConfigList( rs->version() );
00227 DTConfigList::const_iterator iter = rs->begin();
00228 DTConfigList::const_iterator iend = rs->end();
00229 while ( iter != iend ) {
00230 const DTConfigToken& token = iter->second;
00231 std::string actualToken( token.ref );
00232 int actualId = token.id;
00233 if ( ( actualToken == std::string( "dummyToken" ) ) &&
00234 ( actualId > 0 ) ) {
00235 DTConfigToken chkToken;
00236 refSet->ptr()->get( -999999999, chkToken );
00237 actualToken = compToken( chkToken.ref, actualId );
00238 }
00239 cond::TypedRef<DTConfigData> sRef( *dbSession->poolDB(),
00240 actualToken );
00241 std::cout << " copying brick " << sRef->getId() << std::endl;
00242 DTConfigData* ptr = new DTConfigData( *( sRef.ptr() ) );
00243 cond::TypedRef<DTConfigData> dRef( *newSession->poolDB(), ptr );
00244 dRef.markWrite( refContainer );
00245 DTConfigToken objToken;
00246 std::string tokenRef( dRef.token() );
00247 objToken.ref = tokenRef;
00248 objToken.id = compToken( tokenRef );
00249 rn->set( iter->first, objToken );
00250 iter++;
00251 }
00252 cond::TypedRef<DTConfigList> setRef( *newSession->poolDB(), rn );
00253 setRef.markWrite( objContainer );
00254 std::string token = setRef.token();
00255 return token;
00256 }
00257
00258
00259 std::string DTConfigHandler::clone( DTDBSession* newSession,
00260 const std::string& newToken,
00261 const std::string& objContainer,
00262 const std::string& refContainer ) {
00263
00264 if ( !newToken.length() ) return clone( newSession,
00265 objContainer, refContainer );
00266
00267 const DTConfigList* rs = getContainer();
00268 std::cout << "look for existing list reference..." << std::endl;
00269 cond::TypedRef<DTConfigList>* setRef = new cond::TypedRef<DTConfigList>(
00270 *newSession->poolDB(), newToken );
00271 std::cout << "look for existing list pointer..." << std::endl;
00272 DTConfigList* rn = 0;
00273 rn = setRef->ptr();
00274 std::cout << "existing list pointer got " << rn << std::endl;
00275 bool containerMissing = ( rn == 0 );
00276 if ( containerMissing ) rn = new DTConfigList( rs->version() );
00277
00278 DTConfigList::const_iterator iter = rs->begin();
00279 DTConfigList::const_iterator iend = rs->end();
00280 while ( iter != iend ) {
00281 const DTConfigToken& token = iter->second;
00282 std::string actualToken( token.ref );
00283 int actualId = token.id;
00284 if ( ( actualToken == std::string( "dummyToken" ) ) &&
00285 ( actualId > 0 ) ) {
00286 DTConfigToken chkToken;
00287 refSet->ptr()->get( -999999999, chkToken );
00288 actualToken = compToken( chkToken.ref, actualId );
00289 }
00290 cond::TypedRef<DTConfigData> sRef( *dbSession->poolDB(),
00291 actualToken );
00292 int cfgId = sRef->getId();
00293 std::cout << " checking brick " << cfgId << std::endl;
00294 DTConfigToken dumToken;
00295 if ( rn->get( cfgId, dumToken ) ) {
00296 std::cout << " ... copying brick " << cfgId << std::endl;
00297 DTConfigData* ptr = new DTConfigData( *( sRef.ptr() ) );
00298 cond::TypedRef<DTConfigData> dRef( *newSession->poolDB(), ptr );
00299 dRef.markWrite( refContainer );
00300 DTConfigToken objToken;
00301 std::string tokenRef( dRef.token() );
00302 objToken.ref = tokenRef;
00303 objToken.id = compToken( tokenRef );
00304 rn->set( iter->first, objToken );
00305 }
00306 iter++;
00307 }
00308 std::string token( "" );
00309 if ( containerMissing ) {
00310 setRef = new cond::TypedRef<DTConfigList>( *newSession->poolDB(), rn );
00311 setRef->markWrite( objContainer );
00312 token = setRef->token();
00313 }
00314 else {
00315 setRef->markUpdate();
00316 }
00317 return token;
00318 }
00319
00320
00321 std::string DTConfigHandler::compToken( const std::string& refToken, int id ) {
00322 std::string actualToken( "" );
00323 char* buf = new char[9];
00324 unsigned int iofb = 0;
00325 unsigned int iofe = 0;
00326 while ( true ) {
00327 iofb = refToken.find( "[", iofb );
00328
00329 if ( iofb >= refToken.length() ) break;
00330 iofe = refToken.find( "]", iofb );
00331 std::string sub( refToken.substr( iofb, 1 + iofe - iofb ) );
00332 iofb = sub.find( "=", 0 );
00333 std::string key( sub.substr( 1, iofb ) );
00334 if ( key == std::string( "OID=" ) ) {
00335 iofb = 1 + sub.find( "-", 0 );
00336 std::string val( sub.substr( iofb, sub.length() - iofb - 1 ) );
00337 actualToken += sub.substr( 0, iofb );
00338 sprintf( buf, "%8.8x", id );
00339 actualToken += buf;
00340 actualToken += "]";
00341 }
00342 else {
00343 actualToken += sub;
00344 }
00345 iofb = iofe;
00346 }
00347 delete[] buf;
00348 return actualToken;
00349 }
00350
00351
00352 int DTConfigHandler::compToken( const std::string& refToken ) {
00353 unsigned int iofb = 0;
00354 unsigned int iofe = 0;
00355 unsigned tokenId;
00356 while ( true ) {
00357 iofb = refToken.find( "[", iofb );
00358
00359 if ( iofb >= refToken.length() ) break;
00360 iofe = refToken.find( "]", iofb );
00361 std::string sub( refToken.substr( iofb, 1 + iofe - iofb ) );
00362 iofb = sub.find( "=", 0 );
00363 std::string key( sub.substr( 1, iofb ) );
00364 if ( key == std::string( "OID=" ) ) {
00365 iofb = 1 + sub.find( "-", 0 );
00366 std::string val( sub.substr( iofb, sub.length() - iofb - 1 ) );
00367 sscanf( val.c_str(), "%x", &tokenId );
00368 break;
00369 }
00370 iofb = iofe;
00371 }
00372 return tokenId;
00373 }
00374
00375