Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ] 

001 #include <algorithm>
002 #include <cassert>
003 #include <iostream>
004 #include <functional>
005 #include <string>
006 
007 #ifndef HAVE_NEW_IOSTREAMS
008 #include <strstream>  /*gnu-specific*/
009 typedef strstream __sstream;
010 #else
011 #include <sstream>
012 typedef std::ostringstream __sstream;
013 #endif
014 
015 #include <iomanip>
016 using std::setw;
017 
018 #include "AthenaKernel/IClassIDSvc.h"
019 #include "AthenaKernel/IProxyProviderSvc.h"
020 #include "AthenaKernel/IIOVSvc.h"
021 #include "AthenaKernel/errorcheck.h"
022 #include "GaudiKernel/IHistorySvc.h"
023 #include "GaudiKernel/ISvcLocator.h"
024 #include "GaudiKernel/IIncidentSvc.h"
025 #include "GaudiKernel/IConversionSvc.h"
026 #include "GaudiKernel/Incident.h"
027 #include "GaudiKernel/IOpaqueAddress.h"
028 #include "GaudiKernel/MsgStream.h"
029 #include "GaudiKernel/StatusCode.h"
030 #include "GaudiKernel/ThreadGaudi.h"
031 #include "GaudiKernel/DataHistory.h"
032 #include "SGTools/DataBucketBase.h"
033 #include "SGTools/DataProxy.h"
034 #include "SGTools/DataStore.h"
035 #include "SGTools/StringPool.h"
036 #include "SGTools/TransientAddress.h"
037 #include "SGTools/SGVersionedKey.h"
038 #include "SGTools/unordered_map.h"
039 #include "StoreGate/ActiveStoreSvc.h"
040 #include "StoreGate/StoreClearedIncident.h"
041 
042 #include "StoreGate/StoreGateSvc.h"
043 
044 using std::bind1st;
045 using std::find_if;
046 using std::mem_fun;
047 using std::not1;
048 using std::hex;
049 using std::dec;
050 using std::endl;
051 using std::ends;
052 using std::setw;
053 using std::string;
054 
055 using SG::DataProxy;
056 using SG::DataStore;
057 using SG::TransientAddress;
058 
059 ///////////////////////////////////////////////////////////////////////////
060 // Remapping implementation.
061 
062 namespace SG {
063 
064 
065 struct RemapImpl
066 {
067   typedef IStringPool::sgkey_t sgkey_t;
068 
069   // Hash function for the key.
070   // Just cast the low bits to a size_t.
071   struct keyhash
072   {
073     std::size_t operator() (sgkey_t key) const
074     { return static_cast<std::size_t> (key); }
075   };
076 
077   struct remap_t {
078     sgkey_t target;
079     off_t index_offset;
080   };
081   typedef SG::unordered_map<sgkey_t, remap_t, keyhash> remap_map_t;
082   remap_map_t m_remaps;
083 };
084 
085 
086 } // namespace SG
087 
088 ///////////////////////////////////////////////////////////////////////////
089 /// Standard Constructor
090 StoreGateSvc::StoreGateSvc(const string& name,ISvcLocator* svc)
091   : Service(name, svc), m_pIncSvc(0), m_pCLIDSvc(0), m_pDataLoader(0), 
092     m_pPPS(0), m_pHistorySvc(0), m_pStore(new DataStore), 
093     m_DumpStore(false), m_ActivateHistory(false), m_pIOVSvc(0),
094     m_storeLoaded(false),
095     m_remap_impl (new SG::RemapImpl)
096 {
097   declareProperty("Dump", m_DumpStore);
098   declareProperty("ActivateHistory", m_ActivateHistory);
099 }
100 
101 
102 /// Standard Destructor
103 StoreGateSvc::~StoreGateSvc()  {
104   delete m_pStore;
105   delete m_remap_impl;
106 }
107 
108 //////////////////////////////////////////////////////////////
109 /// Service initialisation
110 StatusCode StoreGateSvc::initialize()    {
111 
112   MsgStream msg( messageService(), name() );
113   msg << MSG::INFO << "Initializing " << name() 
114       << " - package version " << PACKAGE_VERSION << endreq ;
115 
116   if(!(Service::initialize()).isSuccess()) {
117     msg << MSG::ERROR << "Could not initialize base Service !!" << endreq;
118     return StatusCode::FAILURE;
119   }
120 
121   // set store ID (ugly!):
122   string generic_name = getGaudiThreadGenericName(name()) ;
123   if (generic_name == "StoreGateSvc" || generic_name == "EventStore") {
124     store()->setStoreID(StoreID::EVENT_STORE);
125   } else if (generic_name == "DetectorStore") {
126     store()->setStoreID(StoreID::DETECTOR_STORE);
127   }  else if (generic_name == "ConditionsStore") {
128     store()->setStoreID(StoreID::CONDITION_STORE);
129   } else if (generic_name == "InputMetaDataStore" || generic_name == "TagMetaDataStore") {
130     store()->setStoreID(StoreID::METADATA_STORE);
131   } else if (generic_name == "MetaDataStore") {
132     store()->setStoreID(StoreID::SIMPLE_STORE);
133   } else if (generic_name == "SpareStore") {
134     store()->setStoreID(StoreID::SPARE_STORE);
135   } else {
136     store()->setStoreID(StoreID::UNKNOWN);
137   }
138 
139   static const bool CREATEIF(true);
140   // set up the incident service:
141   if (!(service("IncidentSvc", m_pIncSvc, CREATEIF)).isSuccess()) {
142     msg << MSG::ERROR 
143         << "Could not locate IncidentSvc "
144         << endreq;
145     return StatusCode::FAILURE;
146   }
147 
148   //start listening to "EndEvent"
149   static const int PRIORITY = 100;
150   m_pIncSvc->addListener(this, "EndEvent", PRIORITY);
151   m_pIncSvc->addListener(this, "BeginEvent", PRIORITY);
152 
153   // cache pointer to Persistency Service
154   if (!(service("EventPersistencySvc", m_pDataLoader, CREATEIF)).isSuccess()) {
155     m_pDataLoader = 0;
156     msg << MSG::ERROR
157         << "Could not get pointer to Persistency Service"
158         << endreq;
159     return StatusCode::FAILURE;;
160   }
161 
162   if (!(service("ClassIDSvc", m_pCLIDSvc, CREATEIF)).isSuccess()) {
163     msg << MSG::ERROR
164         << "Could not get pointer to ClassID Service"
165         << endreq;
166     return StatusCode::FAILURE;;
167   }
168 
169   if (!(service("ProxyProviderSvc", m_pPPS, CREATEIF)).isSuccess()) {
170     msg << MSG::ERROR
171         << "Could not get pointer to ProxyProvider Service"
172         << endreq;
173     return StatusCode::FAILURE;;
174   }
175  
176   if ( 0 == m_pPPS || (m_pPPS->preLoadProxies(*m_pStore)).isFailure() )
177   {
178       msg << MSG::DEBUG
179           << " Failed to preLoad proxies"
180           << endreq;
181       return StatusCode::FAILURE;
182   }
183 
184   // Get hold of History Service
185   if (m_ActivateHistory &&
186       !(service("HistorySvc", m_pHistorySvc, CREATEIF)).isSuccess()) {
187     msg << MSG::ERROR
188         << "Could not locate History Service"
189         << endreq;
190     return StatusCode::FAILURE;
191   }
192 
193   return StatusCode::SUCCESS;
194 }
195 /// Service start
196 StatusCode StoreGateSvc::start()    {
197 
198   MsgStream msg( messageService(), name() );
199   msg << MSG::INFO << "Start " << name() << endreq;
200 /*
201 // This will need regFcn clients to be updated first.
202   if ( 0 == m_pPPS || (m_pPPS->preLoadProxies(*m_pStore)).isFailure() )
203   {
204       msg << MSG::DEBUG
205           << " Failed to preLoad proxies"
206           << endreq;
207       return StatusCode::FAILURE;
208   }
209 */
210   return StatusCode::SUCCESS;
211 }
212 
213 //////////////////////////////////////////////////////////////
214 IIOVSvc* StoreGateSvc::getIIOVSvc() {
215   // Get hold of the IOVSvc
216   if (0 == m_pIOVSvc && !(service("IOVSvc", m_pIOVSvc)).isSuccess()) {
217     MsgStream mlog( msgSvc(), name() );
218     mlog << MSG::WARNING
219         << "Could not locate IOVSvc "
220         << endreq;
221   }
222   return m_pIOVSvc;
223 }
224 
225 //////////////////////////////////////////////////////////////
226 void StoreGateSvc::handle(const Incident &inc) {
227   MsgStream log( messageService(), name() );
228 
229   if ( inc.type() == "EndEvent" && m_DumpStore) 
230   {
231     // dump store:
232 
233     log << MSG::DEBUG 
234         << "Dumping StoreGate Contents" 
235         << endreq;
236     log << MSG::INFO 
237         << '\n' << dump() << endl 
238         << endreq;
239 
240   }
241   // NO MORE this is now done by the event loop mgrs
242   //  else if ( inc.type() == "BeginEvent") 
243   //  {
244   //     if ( loadEventProxies().isFailure() )
245   //     {
246   //       log << MSG::DEBUG
247   //      << " Failed to load proxies at Begin Event "
248   //      << endreq;
249   //     }
250   //  }
251 }
252 
253 StatusCode StoreGateSvc::loadEventProxies() {
254   StatusCode sc(StatusCode::SUCCESS);
255   //FIXME this should probably be dealt with by the providers
256   if (0 != m_pPPS && !m_storeLoaded) {
257     m_storeLoaded = true;
258     //this (probably) can't be done in initialize (circular init!)
259     ActiveStoreSvc* pActive(0);
260     const bool CREATEIF(true);
261     if (!(serviceLocator()->service("ActiveStoreSvc", pActive, CREATEIF)).isSuccess()) return StatusCode::FAILURE;
262     pActive->setStore(this);
263     sc=m_pPPS->loadProxies(*m_pStore);
264   } 
265   return sc;
266 }
267 
268 ///////////////////////////////////////////////////////////////////
269 // Create a key for a type (used if the client has not specified a key)
270 string StoreGateSvc::createKey(const CLID& id)
271 {
272   __sstream o;
273   o << m_pStore->typeCount(id)+1 << std::ends;
274   string ret(o.str());
275 #ifndef HAVE_NEW_IOSTREAMS
276   o.freeze(false);
277 #endif
278   return ret;
279 }
280 //////////////////////////////////////////////////////////////
281 // clear store
282 StatusCode StoreGateSvc::clearStore(bool forceRemove)
283 {
284   emptyTrash();
285   assert(m_pStore);
286   MsgStream mlog( messageService(), name() );
287   MsgStream* pmlog( (messageService()->outputLevel(name()) <= MSG::VERBOSE) ? &mlog : 0);
288   m_pStore->clearStore(forceRemove, pmlog);
289   m_storeLoaded=false;  //FIXME hack needed by loadEventProxies
290   m_remap_impl->m_remaps.clear();
291 
292   // Send a notification that the store was cleared.
293   if (m_pIncSvc)
294     m_pIncSvc->fireIncident (StoreClearedIncident (this, name()));
295 
296   return StatusCode::SUCCESS;
297 }
298 //////////////////////////////////////////////////////////////
299 /// Service finalisation
300 StatusCode StoreGateSvc::finalize()    {
301   MsgStream mlog( messageService(), name() );
302   mlog << MSG::INFO << "Finalizing " << name() 
303       << " - package version " << PACKAGE_VERSION << endreq ;
304   const bool FORCEREMOVE(true);
305 
306   // Incident service may not work in finalize.
307   // Clear this, so that we won't try to send an incident from clearStore.
308   if (m_pIncSvc) {
309     m_pIncSvc->release();
310     m_pIncSvc = 0;
311   }
312 
313 
314   clearStore(FORCEREMOVE).ignore();
315 
316   //protect against double release
317   if (m_pHistorySvc) {
318     m_pHistorySvc->release();
319     m_pHistorySvc = 0;
320   }
321 
322   return Service::finalize();
323 }
324 //////////////////////////////////////////////////////////////
325 /// Service reinitialization
326 StatusCode StoreGateSvc::reinitialize()    {
327   MsgStream mlog( messageService(), name() );
328   mlog << MSG::INFO << "Reinitializing " << name() 
329       << " - package version " << PACKAGE_VERSION << endreq ;
330   const bool FORCEREMOVE(true);
331   clearStore(FORCEREMOVE).ignore();
332   //not in v20r2p2! return Service::reinitialize();
333   return StatusCode::SUCCESS;
334 }
335 
336 const InterfaceID& 
337 StoreGateSvc::interfaceID() { 
338   static const InterfaceID _IID("StoreGateSvc", 1, 0);
339   return _IID; 
340 }
341 
342   // Query the interfaces.
343   //   Input: riid, Requested interface ID
344   //          ppvInterface, Pointer to requested interface
345   //   Return: StatusCode indicating SUCCESS or FAILURE.
346   // N.B. Don't forget to release the interface after use!!!
347 StatusCode StoreGateSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) 
348 {
349   if ( IProxyDict::interfaceID().versionMatch(riid) )    {
350     *ppvInterface = (IProxyDict*)this;
351   } else if ( interfaceID().versionMatch(riid) )    {
352     // In principle this should be cast to IStoreGateSvc*. However, there
353     // is an anomaly in that existing clients are using the concrete StoreGate
354     // interface instread of an abstract IStoreGateSvc interface.
355     *ppvInterface = (StoreGateSvc*)this;
356   } else  {
357     // Interface is not directly available: try out a base class
358     return Service::queryInterface(riid, ppvInterface);
359   }
360   addRef();
361   return StatusCode::SUCCESS;
362 }
363 
364 //////////////////////////////////////////////////////////////////
365 //////////////////////////////////////////////////////////////////////
366 // add proxy (with IOpaqueAddress that will later be retrieved from P)
367 //////////////////////////////////////////////////////////////////////
368 StatusCode StoreGateSvc::recordAddress(IOpaqueAddress* pAddress, bool clearAddressFlag)
369 {
370   assert(0 != pAddress);
371   CLID dataID = pAddress->clID();
372 
373   if (dataID == 0)
374   {
375     MsgStream log( messageService(), name() );
376     log << MSG::WARNING
377         << "recordAddress: Invalid Class ID found in IOpaqueAddress @" 
378         << pAddress << ". IOA will not be recorded"
379         << endreq;
380         return StatusCode::FAILURE;
381   }
382 
383   string gK = (pAddress->par())[0];   // FIXME
384 
385   if (gK == "") gK = createKey(dataID);
386 
387   // Check if a key already exists
388   DataProxy* dp = m_pStore->proxy_exact(dataID, gK);
389 
390   // Now treat the various cases:
391   if (0 == dp) 
392   {
393     // create the proxy object and register it
394     TransientAddress* tAddr = new TransientAddress(dataID, gK, 
395                                                    pAddress, clearAddressFlag);
396     m_pStore->addToStore(dataID, new DataProxy(tAddr, m_pDataLoader,
397                                                true, true)).ignore();
398   }
399   else if ((0 != dp) && (0 == dp->address()))
400   // Note: intentionally not checking dp->isValidAddress()
401   {
402     // Update proxy with IOpaqueAddress
403     dp->setAddress(pAddress);
404   }
405   else
406   {
407     string errType;
408     m_pCLIDSvc->getTypeNameOfID(dataID, errType).ignore();
409     MsgStream log( messageService(), name() );
410     log << MSG::WARNING
411         << "recordAddress: preexisting proxy @" << dp
412         << " with non-NULL IOA found for key " 
413         << gK << " type " << errType << " (" << dataID << "). \n"
414         << "Cannot record IOpaqueAddress @" << pAddress
415         << endreq;
416     return StatusCode::FAILURE;
417   }
418 
419   return StatusCode::SUCCESS;
420 
421 }    
422 
423 DataProxy* StoreGateSvc::setupProxy(const CLID& dataID, 
424                                     const string& gK, 
425                                     DataObject* pDObj,
426                                     bool allowMods, 
427                                     bool resetOnly) {
428   // locate the proxy           
429   DataProxy* dp = m_pStore->proxy_exact(dataID, gK);
430   
431   if (0 != dp) { //proxy found  
432     if (0 != dp->object())
433     {
434       // Case 0: duplicated proxy               
435       MsgStream log( messageService(), name() );
436       log << MSG::WARNING << " setupProxy:: error setting up proxy for key " 
437           << gK << " and clid " << dataID
438           << "\n Pre-existing valid DataProxy @"<< dp 
439           << " found in Store for key " <<  dp->object()->name()
440           << " with clid " << dp->object()->clID()
441           << endreq;
442       recycle(pDObj);      // commit this object to trash
443       dp = 0;
444     } else {
445       // Case 1: Proxy found... if not valid, update it:
446       dp->setObject(pDObj);
447       if (!allowMods) dp->setConst();
448     } 
449   } else {
450     // Case 2: No Proxy found:
451     TransientAddress* tAddr = new TransientAddress(dataID, gK);
452     dp = new DataProxy(pDObj, tAddr, !allowMods, resetOnly);
453     if (!(m_pStore->addToStore(dataID, dp).isSuccess())) {
454       MsgStream log( messageService(), name() );
455       log << MSG::WARNING << " setupProxy:: could not addToStore proxy @" << dp
456           << endreq;
457       recycle(pDObj);      // commit this object to trash
458       delete dp;
459       dp = 0;
460     }
461   }
462   return dp;
463 }
464 
465 /// set store id in DataStore:
466 void StoreGateSvc::setStoreID(StoreID::type id)
467 {
468   store()->setStoreID(id);
469 }
470 
471 // return keys for a given object (clid)
472 std::vector<std::string> StoreGateSvc::keys(const CLID& id, bool allKeys)
473 { 
474   return store()->keys(id, allKeys);
475 } 
476 
477 bool StoreGateSvc::isSymLinked(const CLID& linkID, DataProxy* dp)        
478 {        
479   return (0 != dp) ? dp->transientAddress()->transientID(linkID) : false;        
480 }
481 
482 //////////////////////////////////////////////////////////////////
483 // Dump Contents in store:
484 string StoreGateSvc::dump() const
485 { 
486   __sstream ost;
487   ost << "<<<<<<<<<<<<<<<<< Data Store Dump >>>>>>>>>>>>>>> \n";
488   ost << "StoreGateSvc(" + name() + ")::dump():\n";
489 
490   DataStore::ConstStoreIterator s_iter, s_end;
491   store()->tRange(s_iter, s_end).ignore();
492 
493   for (; s_iter != s_end; s_iter++) 
494   {
495 
496     CLID id = s_iter->first;
497     int nProxy = store()->typeCount(id);
498     string tname;
499     m_pCLIDSvc->getTypeNameOfID(id, tname).ignore();
500     ost << "Found " << nProxy << ((nProxy == 1) ? " proxy" : " proxies") 
501         << " for ClassID " << id <<" ("<< tname << "): \n";
502 
503     // loop over each type:
504     SG::ConstProxyIterator p_iter = (s_iter->second).begin();
505     SG::ConstProxyIterator p_end =  (s_iter->second).end();
506   
507     while (p_iter != p_end) {
508       const DataProxy& dp(*p_iter->second);
509       ost << " flags: (" 
510           << setw(7) << (dp.isValid() ? "valid" : "INVALID") << ", "
511           << setw(8) << (dp.isConst() ? "locked" : "UNLOCKED") << ", "
512           << setw(6) << (dp.isResetOnly() ? "reset" : "DELETE")
513           << ") --- data: " << hex << setw(10) << dp.object() << dec
514           << " --- key: " << p_iter->first << '\n';
515       ++p_iter;
516     }
517   }
518   ost << "<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>> \n" <<ends;
519   string ret(ost.str());
520 #ifndef HAVE_NEW_IOSTREAMS
521   ost.freeze(false);
522 #endif
523   return ret;
524 
525 }
526  
527 DataStore* 
528 StoreGateSvc::store() 
529 { 
530   return m_pStore; 
531 }
532 
533 const DataStore* 
534 StoreGateSvc::store() const 
535 { 
536   return m_pStore; 
537 }
538 
539  
540 StatusCode
541 StoreGateSvc::addSymLink(const CLID& linkid, DataProxy* dp)
542 { 
543   if (0 == dp) {
544     MsgStream log( messageService(), name() );
545     log << MSG::WARNING
546         << "addSymLink: no target DataProxy found. Sorry, can't link to a non-existing data object"
547         << endreq;
548     return StatusCode::FAILURE;
549   } 
550   StatusCode sc = m_pStore->addSymLink(linkid, dp); 
551 
552   // If the symlink is a derived->base conversion, then we may have
553   // a different transient pointer for the symlink.
554   if (sc.isSuccess()) {
555     void* baseptr = SG::DataProxy_cast (dp, linkid);
556     m_pStore->t2pRegister (baseptr, dp).ignore();
557   }
558   return sc;
559 }
560 
561  
562 StatusCode
563 StoreGateSvc::addAlias(const std::string& aliasKey, DataProxy* proxy)
564 {
565   if (0 == proxy) {
566     MsgStream log(messageService(), name());
567     log << MSG::WARNING
568         << "addAlias: no target DataProxy given, Cannot alias to a non-existing object" 
569         << endreq;
570     return StatusCode::FAILURE;
571   }
572 
573   // add key to proxy and to ProxyStore
574   return m_pStore->addAlias(aliasKey, proxy);
575 }
576 
577 int StoreGateSvc::typeCount(const CLID& id) const
578 {
579   return m_pStore->typeCount(id);
580 }  
581 
582 DataProxy* 
583 StoreGateSvc::proxy(const void* const pTransient) const
584 { 
585   return m_pStore->locatePersistent(pTransient); 
586 }
587 
588 DataProxy* 
589 StoreGateSvc::deep_proxy(const void* const pTransient) const
590 { 
591   return this->proxy (pTransient);
592 }
593 
594 DataProxy* 
595 StoreGateSvc::proxy(const CLID& id) const
596 { 
597   return proxy(id, false);
598 }
599 
600 DataProxy* 
601 StoreGateSvc::proxy(const CLID& id, bool checkValid) const
602 { 
603   DataProxy* dp = m_pStore->proxy(id);
604 
605   /// Check if it is valid
606   if (checkValid && 0 != dp) {
607     // FIXME: For keyless retrieve, this checks only the first instance
608     // of the CLID in store. If that happens to be invalid, but the second
609     // is valid - this does not work (when checkValid is requested).
610     return dp->isValid() ? dp : 0;
611   }
612   //  } else if (0 == dp) {
613   //    dp = m_pPPS->retrieveProxy(id, string("DEFAULT"), *m_pStore);
614   //  }
615   return dp;
616 }
617 
618 DataProxy* 
619 StoreGateSvc::proxy(const CLID& id, const string& key) const
620 { 
621   return proxy(id, key, false);
622 }
623 
624 DataProxy*
625 StoreGateSvc::proxy(const CLID& id, const string& key, bool checkValid) const
626 { 
627   DataProxy* dp = m_pStore->proxy(id, key);
628   if (0 == dp && 0 != m_pPPS) {
629     dp = m_pPPS->retrieveProxy(id, key, *m_pStore);
630   }
631   if (checkValid && 0 != dp && !(dp->isValid())) dp = 0;
632   return dp;
633 }
634 
635 std::vector<const SG::DataProxy*> 
636 StoreGateSvc::proxies() const
637 {
638   using std::distance;
639   DataStore::ConstStoreIterator s_iter, s_end;
640   store()->tRange(s_iter, s_end).ignore();
641 
642   std::vector<const SG::DataProxy*> proxies;
643   proxies.reserve( distance( s_iter, s_end ) );
644 
645   for (; s_iter != s_end; ++s_iter ) {
646 
647     const CLID id = s_iter->first;
648     proxies.reserve( proxies.size() + store()->typeCount(id) );
649 
650     // loop over each type:
651     SG::ConstProxyIterator p_iter = (s_iter->second).begin();
652     SG::ConstProxyIterator p_end =  (s_iter->second).end();
653 
654     for ( ; p_iter != p_end; ++p_iter ) {
655       proxies.push_back( p_iter->second );
656     }
657   }
658 
659   return proxies;
660 }
661 
662 DataProxy*
663 StoreGateSvc::transientProxy(const CLID& id, const string& key) const
664 { 
665   DataProxy* dp(m_pStore->proxy(id, key));
666   return ( (0 != dp && dp->isValidObject()) ? dp : 0 );
667 }
668 
669 DataObject* 
670 StoreGateSvc::accessData(const CLID& id) const
671 { 
672   DataProxy* theProxy(proxy(id, true));
673   return (0 == theProxy) ? 0 : theProxy->accessData();
674 }
675 
676 DataObject* 
677 StoreGateSvc::accessData(const CLID& id, const string& key) const
678 { 
679   DataProxy* theProxy(proxy(id, key, true));
680   return (0 == theProxy) ? 0 : theProxy->accessData();
681 }
682 
683 bool
684 StoreGateSvc::transientSwap( const CLID& id,
685                              const std::string& keyA, const std::string& keyB )
686 {
687   const bool checkValid = true;
688   DataProxy* a = proxy( id, keyA, checkValid );
689   DataProxy* b = proxy( id, keyB, checkValid );
690   if ( 0 == a || 0 == b ) { return false; }
691   DataObject* objA = a->accessData();
692   DataObject* objB = b->accessData();
693 
694   if ( 0 == objA || 0 == objB ) { return false; }
695   // prevent 'accidental' release of DataObjects...
696   const unsigned int refCntA = objA->addRef(); 
697   const unsigned int refCntB = objB->addRef();
698   // in case swap is being specialized for DataObjects 
699   using std::swap;
700   swap( objA, objB );
701   a->setObject( objA );
702   b->setObject( objB );
703   // and then restore old ref-count;
704   return ( (refCntA-1) == objA->release() && 
705            (refCntB-1) == objB->release() );
706 }
707 
708 StatusCode
709 StoreGateSvc::typeless_record( DataObject* obj, const std::string& key,
710                                const void* const raw_ptr,
711                                bool allowMods, bool resetOnly, bool noHist )
712 {
713   if ( record_impl( obj, key, raw_ptr, allowMods, resetOnly ).isFailure() ) {
714     return StatusCode::FAILURE;
715   }
716 
717   if ( !m_ActivateHistory || noHist ) {
718     return StatusCode::SUCCESS;
719   }
720 
721   if ( store()->storeID() != StoreID::EVENT_STORE ) {
722     return StatusCode::SUCCESS;
723   } else {
724     return record_HistObj( obj->clID(), key, name(), allowMods, resetOnly );
725   }
726 }
727 
728 StatusCode
729 StoreGateSvc::record_impl( DataObject* pDObj, const std::string& key,
730                            const void* const raw_ptr,
731                            bool allowMods, bool resetOnly )
732 {
733   CLID clid = pDObj->clID();
734   //first of all check whether raw_ptr has already been recorded
735   //We need to do this before we create the bucket, the proxy etc
736   SG::DataProxy* dp(proxy(raw_ptr));
737   if (0 != dp) {
738     std::string clidTypeName; 
739     m_pCLIDSvc->getTypeNameOfID(clid, clidTypeName).ignore();
740     MsgStream msg( messageService(), name() );
741     msg << MSG::WARNING
742         << "record: failed for key="<< key << ", type "  << clidTypeName
743         << " (CLID " << clid << ')' 
744         << "\n object @" << raw_ptr 
745         << " already in store with key="<< dp->name()
746         << ". Will not record a duplicate! "
747         << endreq;
748     DataBucketBase* pDBB(dynamic_cast<DataBucketBase*>(pDObj));
749     if (pDBB) pDBB->relinquish(); //don't own the data obj already recorded!
750     this->recycle(pDObj);
751     return StatusCode::FAILURE;
752   }
753 
754   // setup the proxy
755   dp = setupProxy( clid, key, pDObj, allowMods, resetOnly );
756   if ( 0 == dp ) {
757     std::string clidTypeName; 
758     m_pCLIDSvc->getTypeNameOfID(clid, clidTypeName).ignore();
759     MsgStream msg( messageService(), name() );
760     msg << MSG::WARNING
761         << "record: Problem setting up the proxy for object @" <<raw_ptr 
762         << "\n recorded with key " << key 
763         << " of type "  << clidTypeName
764         << " (CLID " << clid << ") in DataObject @" << pDObj
765         << endreq;
766 
767     return StatusCode::FAILURE;
768   }
769 
770   // record in t2p:
771   if ( !(t2pRegister( raw_ptr, dp )).isSuccess() ) {
772     std::string clidTypeName; 
773     m_pCLIDSvc->getTypeNameOfID(clid, clidTypeName).ignore();
774     MsgStream msg( messageService(), name() );
775     msg << MSG::WARNING
776         << "record: can not add to t2p map object @" <<raw_ptr 
777         << "\n with key " << key 
778         << " of type "  << clidTypeName
779         << " (CLID " << clid << ')' 
780         << endreq;
781     return StatusCode::FAILURE;
782   }
783 
784   // Automatically make all legal base class symlinks
785   const SG::BaseInfoBase* bib = SG::BaseInfoBase::find( clid );
786   if ( bib ) {
787     std::vector<CLID> bases = bib->get_bases();
788     for ( std::size_t i = 0, iMax = bases.size(); i < iMax; ++i ) {
789       if ( bases[i] != clid ) {
790         if ( addSymLink( bases[i], dp ).isSuccess() ) {
791           // register with t2p
792           this->t2pRegister( SG::DataProxy_cast( dp, bases[i] ), dp ).ignore();
793         }
794         else {
795           MsgStream msg( messageService(), name() );
796           msg << MSG::WARNING
797               << "Doing auto-symlinks for object with CLID " << clid
798               << " and SG key " << key 
799               << ": Proxy already set for base CLID " << bases[i]
800               << "; not making auto-symlink." << endmsg;
801         }
802       }
803     }
804   } else {
805     MsgStream msg( msgSvc(), name() );
806     msg << MSG::WARNING
807         << "Could not find suitable SG::BaseInfoBase for CLID ["
808         << clid << "] !\t"
809         << "No auto-symlink established !"
810         << endreq;
811   }
812 
813   //handle versionedKeys: we register an alias with the "true" key
814   //unless an object as already been recorded with that key.
815   //Notice that addAlias overwrites any existing alias, so a generic
816   //retrieve will always return the last version added 
817   //FIXME not the one with the highest version
818   if (SG::VersionedKey::isVersionedKey(key)) {
819     SG::VersionedKey vk(key);
820     std::string trueKey(vk.key());
821     //first check if we have already a proxy for trueKey
822     if (0 == this->proxy(clid,trueKey)) {
823       //if none found add the alias
824       if (!(this->addAlias(trueKey, dp)).isSuccess()) {
825         MsgStream msg( msgSvc(), name() );
826         msg << MSG::WARNING
827             << "Could not setup alias key " << trueKey 
828             << " for VersionedKey " << key
829             << ". Generic access to this object with clid" << clid 
830             << " will not work"
831             << endreq;      
832       }
833     }
834   }
835 
836   return StatusCode::SUCCESS;
837   
838 }
839 
840 DataProxy*
841 StoreGateSvc::locatePersistent(const TransientAddress* tAddr, 
842                                bool checkValid) const
843 { 
844   DataProxy* dp = m_pStore->proxy(tAddr);
845   
846   if (checkValid && 0 != dp) {
847     return dp->isValid() ? dp : 0;
848   } else {
849     return dp;
850   }
851 }
852 
853 StatusCode
854 StoreGateSvc::removeProxy(DataProxy* proxy, const void* const pTrans, 
855                           bool resetOnly)
856 {
857   // check if valid proxy
858   if (0 == proxy || 0 == pTrans) return StatusCode::FAILURE;
859 
860   // remove all entries from t2p map
861   t2pRemove(pTrans);
862   SG::DataProxy::CLIDCont_t clids = proxy->transientID();
863   for (SG::DataProxy::CLIDCont_t::const_iterator i = clids.begin();
864        i != clids.end();
865        ++i)
866   {
867     void* ptr = SG::DataProxy_cast (proxy, *i);
868     t2pRemove(ptr);
869   }
870 
871   // remove from store
872   return m_pStore->removeProxy(proxy, resetOnly);
873 }
874 
875 StatusCode
876 StoreGateSvc::t2pRegister(const void* const pTrans, DataProxy* const pPers)
877 { 
878   return m_pStore->t2pRegister(pTrans, pPers);
879 }
880 
881 
882 void
883 StoreGateSvc::t2pRemove(const void* const pTrans)
884 { m_pStore->t2pRemove(pTrans); }
885 
886 StatusCode 
887 StoreGateSvc::proxyRange(const CLID& id,
888                          SG::ConstProxyIterator& begin,
889                          SG::ConstProxyIterator& end) const {
890   return m_pStore->pRange(id,begin,end);
891 }
892 
893 StatusCode StoreGateSvc::setConst(const void* pObject)
894 {
895   // Check if dataproxy does not exist
896   DataProxy * dp = proxy(pObject); 
897 
898   if (0 == dp)
899   {
900     MsgStream log( messageService(), name() );
901     log << MSG::WARNING
902         << "setConst: NO Proxy for the dobj you want to set const"
903         << endreq;
904     return StatusCode::FAILURE;
905   }
906 
907   dp->setConst();
908   return StatusCode::SUCCESS;
909 }
910 
911 //put a bad (unrecordable) dobj away
912 void StoreGateSvc::recycle(DataObject* pBadDObj) {
913   assert(pBadDObj);
914   //DataObject::release won't delete an object refCount==0
915   if (0 == pBadDObj->refCount()) pBadDObj->addRef(); 
916     m_trash.push_back(pBadDObj);
917 }
918 
919 //throw away bad objects
920 void StoreGateSvc::emptyTrash() {
921   while (!m_trash.empty()) {
922     m_trash.front()->release();  //delete the bad data object
923     m_trash.pop_front();     //remove pointer from list
924   }
925 }
926 
927 
928 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
929 
930 bool StoreGateSvc::bindHandleToProxy(const CLID& id, const string& key,
931                                      IResetable* ir, DataProxy *&dp) 
932 {
933 
934   dp = (0 == m_pPPS) ? 0 : m_pPPS->retrieveProxy(id, key, *m_pStore);
935 
936   if (0 == dp) return false;
937 
938   dp->bindHandle(ir);
939 
940 #ifndef NDEBUG
941     MsgStream log( messageService(), name() );
942 #ifndef HAVE_NEW_IOSTREAMS
943     log << MSG::DEBUG
944         << " Bound handle " << hex << ir << " to proxy " 
945         << dp << dec 
946         << endreq;
947 #else
948     log << MSG::DEBUG
949         << " Bound handle " << MSG::hex << ir << " to proxy " 
950         << dp << MSG::dec 
951         << endreq;
952 #endif
953 #endif
954     return true;
955 }
956 
957 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
958 
959 StatusCode 
960 StoreGateSvc::record_HistObj(const CLID& id, const std::string& key,
961                              const std::string& store, 
962                              bool allowMods, bool resetOnly) {
963 
964   assert(m_pHistorySvc);
965 
966   DataHistory *dho;
967   dho = m_pHistorySvc->createDataHistoryObj( id, key, store );
968 
969   std::string idname;
970   StatusCode sc = m_pCLIDSvc->getTypeNameOfID(id, idname);
971   if (sc.isFailure() || idname == "" ) { 
972     std::ostringstream ost;
973     ost << id;
974     idname = ost.str();
975   }
976   idname = idname + "/" + key;
977 
978   DataObject* obj = asStorable<DataHistory>(dho);
979 
980   return record_impl(obj, idname, dho, allowMods, resetOnly);
981 }
982 
983 
984 /**
985  * @brief Find the key for a string/CLID pair.
986  * @param str The string to look up.
987  * @param clid The CLID associated with the string.
988  * @return A key identifying the string.
989  *         A given string will always return the same key.
990  *         Will abort in case of a hash collision!
991  */
992 StoreGateSvc::sgkey_t
993 StoreGateSvc::stringToKey (const std::string& str, CLID clid)
994 {
995   return m_stringpool.stringToKey (str, clid);
996 }
997 
998 
999 /**
1000  * @brief Find the string corresponding to a given key.
1001  * @param key The key to look up.
1002  * @return Pointer to the string found, or null.
1003  *         We can find keys as long as the corresponding string
1004  *         was given to either @c stringToKey() or @c registerKey().
1005  */
1006 const std::string* StoreGateSvc::keyToString (sgkey_t key) const
1007 {
1008   return m_stringpool.keyToString (key);
1009 }
1010 
1011 
1012 /**
1013  * @brief Find the string and CLID corresponding to a given key.
1014  * @param key The key to look up.
1015  * @param clid[out] The found CLID.
1016  * @return Pointer to the string found, or null.
1017  *         We can find keys as long as the corresponding string
1018  *         was given to either @c stringToKey() or @c registerKey().
1019  */
1020 const std::string*
1021 StoreGateSvc::keyToString (sgkey_t key, CLID& clid) const
1022 {
1023   return m_stringpool.keyToString (key, clid);
1024 }
1025 
1026 
1027 /**
1028  * @brief Remember an additional mapping from key to string/CLID.
1029  * @param key The key to enter.
1030  * @param str The string to enter.
1031  * @param clid The CLID associated with the string.
1032  * @return True if successful; false if the @c key already
1033  *         corresponds to a different string.
1034  *
1035  * This registers an additional mapping from a key to a string;
1036  * it can be found later through @c lookup() on the string.
1037  * Logs an error if @c key already corresponds to a different string.
1038  */
1039 void StoreGateSvc::registerKey (sgkey_t key,
1040                                 const std::string& str,
1041                                 CLID clid)
1042 {
1043   if (!m_stringpool.registerKey (key, str, clid)) {
1044     CLID clid2;
1045     const std::string* str2 = m_stringpool.keyToString (key, clid2);
1046     REPORT_MESSAGE (MSG::WARNING) << "The numeric key " << key
1047                                 << " maps to multiple string key/CLID pairs: "
1048                                 << *str2 << "/" << clid2 << " and "
1049                                 << str << "/" << clid;
1050   }
1051 }
1052 
1053 void
1054 StoreGateSvc::releaseObject(const CLID& id, const std::string& key) {
1055   DataProxy *pP(0);
1056   if (0 != (pP = proxy(id, key))) {
1057     // remove all entries from t2p map
1058     SG::DataProxy::CLIDCont_t clids = pP->transientID();
1059     SG::DataProxy::CLIDCont_t::const_iterator i(clids.begin()), e(clids.end());
1060     while (i != e) t2pRemove(SG::DataProxy_cast (pP, *i++));
1061     DataBucketBase *pDBB(dynamic_cast<DataBucketBase*>(pP->object()));
1062     //tell the bucket to let go of the data object
1063     if (0 != pDBB) pDBB->relinquish(); //somebody else better took ownership
1064     pP->reset();
1065   }
1066 }
1067 
1068 
1069 /**
1070  * @brief Declare a remapping.
1071  * @brief source Key hash of the container being remapped.
1072  * @brief target Key hash of the container being remapped to.
1073  * @brief index_offset Amount by which the index should be adjusted
1074  *        between the two containers.
1075  */
1076 void StoreGateSvc::remap_impl (sgkey_t source,
1077                                sgkey_t target,
1078                                off_t index_offset)
1079 {
1080   SG::RemapImpl::remap_t payload;
1081   payload.target = target;
1082   payload.index_offset = index_offset;
1083   m_remap_impl->m_remaps[source] = payload;
1084 }
1085 
1086 
1087 /**
1088  * @brief Test to see if the target of an ElementLink has moved.
1089  * @param sgkey_in Original hashed key of the EL.
1090  * @param index_in Original index of the EL.
1091  * @param sgkey_out[out] New hashed key for the EL.
1092  * @param index_out[out] New index for the EL.
1093  * @return True if there is a remapping; false otherwise.
1094  */
1095 bool StoreGateSvc::tryELRemap (sgkey_t sgkey_in, size_t index_in,
1096                                sgkey_t& sgkey_out, size_t& index_out)
1097 {
1098   SG::RemapImpl::remap_map_t::iterator i =
1099     m_remap_impl->m_remaps.find (sgkey_in);
1100   if (i == m_remap_impl->m_remaps.end())
1101     return false;
1102   const SG::RemapImpl::remap_t& payload = i->second;
1103   sgkey_out = payload.target;
1104   index_out = index_in + payload.index_offset;
1105   return true;
1106 }
1107 
1108 DataObject* StoreGateSvc::typeless_readPrivateCopy(const CLID& clid,
1109                                                    const std::string& key) {
1110   DataObject *pObj(0);
1111   DataProxy *p(this->proxy(clid, key));
1112   if (p) {
1113     if (p->object()) { //this looks in transient mem only
1114       //if there is a dobj in transient memory we take ownership with addRef
1115       p->addRef();
1116       //and make the store forget about the proxy for a moment
1117       const bool FORCEREMOVE(true);      
1118       store()->removeProxy(p, FORCEREMOVE).ignore();
1119       //now we try to read the object from disk. Relies on PPS to reload proxy
1120       DataProxy *pDisk(this->proxy(clid, key));
1121       if (pDisk) {
1122         //We are managing the pObj so we addRef it
1123         if ( (pObj = pDisk->accessData()) ) pObj->addRef();
1124         //don't need this guy anymore, notice we use the StoreGateSvc version
1125         //to remove the t2p entry as well
1126         removeProxy(pDisk, SG::DataProxy_cast(pDisk,clid), FORCEREMOVE).ignore();
1127       }
1128       //replace the "transient" proxy where it was
1129       store()->addToStore(clid, p);
1130     } else if ( (pObj = p->accessData()) ) { //try reading from disk
1131       //We are managing the pObj so we addRef it
1132       pObj->addRef();
1133       //and make the proxy forget about it
1134       p->reset();
1135     }
1136   }
1137   if (0 == pObj) {
1138     string errType;
1139     m_pCLIDSvc->getTypeNameOfID(clid, errType).ignore();
1140     MsgStream mlog(messageService(), name() );
1141     mlog << MSG::WARNING << "typeless_record: did not find object of type "
1142          << errType << " with key " << key << endmsg;
1143   }
1144   return pObj;
1145 }
1146 
1147 
1148 // This is intended to be called from the debugger.
1149 void SG_dump (StoreGateSvc* sg)
1150 {
1151   std::cout << sg->dump() << "\n";
1152 }
1153 
1154 

source navigation ] diff markup ] identifier search ] general search ]

Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems
This page was automatically generated by the LXR engine. Valid HTML 4.01!