Gaudi Framework, version v23r5

Home   Generated: Wed Nov 28 2012
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MultiStoreSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // MultiStoreSvc.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient event data service.
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | MF
15 // +---------+----------------------------------------------+---------
16 //
17 //====================================================================
18 #define DATASVC_MULTISTORESVC_CPP
19 
20 // Include files
21 #include "GaudiKernel/Service.h"
22 #include "GaudiKernel/SmartIF.h"
24 #include "GaudiKernel/MsgStream.h"
25 #include "GaudiKernel/Tokenizer.h"
26 #include "GaudiKernel/SvcFactory.h"
27 #include "GaudiKernel/DataObject.h"
36 
37 #include <map>
38 
39 // Forward declarations
40 // Service factory
41 template <class TYPE> class SvcFactory;
42 // This class
44 
45 typedef const std::string CSTR;
50 
51 namespace {
52 
53  struct Partition {
54  IDataProviderSvc* dataProvider;
55  IDataManagerSvc* dataManager;
57  Partition() : dataProvider(0), dataManager(0)
58  {
59  }
60  Partition(const Partition& entry)
61  : dataProvider(entry.dataProvider),
62  dataManager(entry.dataManager),
63  name(entry.name)
64  {
65  }
66  Partition& operator=(const Partition& entry) {
67  dataProvider = entry.dataProvider;
68  dataManager = entry.dataManager;
69  name = entry.name;
70  return *this;
71  }
72  };
73 }
74 
86 class MultiStoreSvc: public extends3<Service,
87  IDataProviderSvc,
88  IDataManagerSvc,
89  IPartitionControl>
90 {
91 protected:
106  enum { no_type = 0, address_type = 1, object_type = 2};
107  struct tagROOT {
108  int type;
110  union {
113  } root;
114  tagROOT() : type(no_type) { root.address = 0; }
115  } m_root;
117  Partition m_current;
124 
125 public:
127  virtual CLID rootCLID() const {
128  return (CLID)m_rootCLID;
129  }
132  return m_rootName;
133  }
134 
135 // macro to help writing the function calls
136 #define _CALL(P,F,ARGS) \
137  P ? P->F ARGS : IDataProviderSvc::INVALID_ROOT
138 
140  virtual STATUS registerAddress(CSTR& path, ADDRESS* pAddr) {
141  return _CALL(m_current.dataManager, registerAddress, (path, pAddr));
142  }
144  virtual STATUS registerAddress(OBJECT* parent, CSTR& path, ADDRESS* pAddr) {
145  return _CALL(m_current.dataManager, registerAddress, (parent, path, pAddr));
146  }
148  virtual STATUS registerAddress(IRegistry* parent, CSTR& path, ADDRESS* pAdd) {
149  return _CALL(m_current.dataManager, registerAddress, (parent, path, pAdd));
150  }
153  return _CALL(m_current.dataManager, unregisterAddress, (path));
154  }
156  virtual STATUS unregisterAddress(OBJECT* pParent, CSTR& path) {
157  return _CALL(m_current.dataManager, unregisterAddress, (pParent, path));
158  }
161  return _CALL(m_current.dataManager, unregisterAddress, (pParent, path));
162  }
164  virtual STATUS objectLeaves(const OBJECT* pObject, std::vector<IRegistry*>& leaves) {
165  return _CALL(m_current.dataManager, objectLeaves, (pObject, leaves));
166  }
168  virtual STATUS objectLeaves(const IRegistry* pObject, std::vector<IRegistry*>& leaves) {
169  return _CALL(m_current.dataManager, objectLeaves, (pObject, leaves));
170  }
172  virtual STATUS objectParent(const OBJECT* pObject, IRegistry*& refpParent) {
173  return _CALL(m_current.dataManager, objectParent, (pObject, refpParent));
174  }
176  virtual STATUS objectParent(const IRegistry* pObject, IRegistry*& refpParent) {
177  return _CALL(m_current.dataManager, objectParent, (pObject, refpParent));
178  }
181  return _CALL(m_current.dataManager, clearSubTree, (path));
182  }
184  virtual STATUS clearSubTree(OBJECT* pObject) {
185  return _CALL(m_current.dataManager, clearSubTree, (pObject));
186  }
188  virtual STATUS clearStore() {
190  for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
191  (*i).second.dataManager->clearStore().ignore();
192  }
193  if ( m_root.root.object ) {
194  switch ( m_root.type ) {
195  case address_type:
197  break;
198  case object_type:
200  break;
201  }
202  m_root.root.object = 0;
203  }
204  m_root.path = "";
205  m_root.type = no_type;
206  return STATUS::SUCCESS;
207  }
209  virtual STATUS traverseSubTree(CSTR& path, AGENT* pAgent) {
210  return _CALL(m_current.dataManager, traverseSubTree, (path, pAgent));
211  }
213  virtual STATUS traverseSubTree(OBJECT* pObject, AGENT* pAgent) {
214  return _CALL(m_current.dataManager, traverseSubTree, (pObject, pAgent));
215  }
217  virtual STATUS traverseTree( AGENT* pAgent ) {
218  return _CALL(m_current.dataManager, traverseTree, (pAgent));
219  }
222  virtual STATUS setRoot( CSTR& path, OBJECT* pObj) {
223  if ( m_root.root.object ) {
224  switch ( m_root.type ) {
225  case address_type:
227  break;
228  case object_type:
230  break;
231  }
232  }
233  m_root.path = path;
235  m_root.root.object = pObj;
238  }
239 
242  virtual STATUS setRoot (CSTR& path, ADDRESS* pAddr) {
243  if ( m_root.root.object ) {
244  switch ( m_root.type ) {
245  case address_type:
247  break;
248  case object_type:
250  break;
251  }
252  }
253  m_root.path = path;
255  m_root.root.address = pAddr;
256  if ( m_root.root.address ) {
260  }
261  return STATUS::FAILURE;
262  }
264  virtual STATUS setDataLoader(IConversionSvc* pDataLoader) {
266  if ( 0 != pDataLoader ) pDataLoader->addRef();
267  if ( 0 != m_dataLoader ) m_dataLoader->release();
268  if ( 0 != pDataLoader ) {
269  pDataLoader->setDataProvider(this);
270  }
271  m_dataLoader = pDataLoader;
272  for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
273  (*i).second.dataManager->setDataLoader(m_dataLoader).ignore();
274  }
275  return SUCCESS;
276  }
279  return _CALL(m_current.dataProvider, addPreLoadItem, (item));
280  }
283  return _CALL(m_current.dataProvider, addPreLoadItem, (item));
284  }
287  return _CALL(m_current.dataProvider, removePreLoadItem, (item));
288  }
291  return _CALL(m_current.dataProvider, removePreLoadItem, (item));
292  }
294  virtual STATUS resetPreLoad() {
295  return _CALL(m_current.dataProvider, resetPreLoad, ());
296  }
298  virtual STATUS preLoad() {
299  return _CALL(m_current.dataProvider, preLoad, ());
300  }
302  virtual STATUS registerObject(CSTR& path, OBJECT* pObj) {
303  return registerObject(0, path, pObj);
304  }
306  virtual STATUS registerObject(CSTR& parent, CSTR& obj, OBJECT* pObj) {
307  return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj));
308  }
310  virtual STATUS registerObject(CSTR& parent, int item, OBJECT* pObj) {
311  return _CALL(m_current.dataProvider, registerObject, (parent, item, pObj));
312  }
314  virtual STATUS registerObject(OBJECT* parent, CSTR& obj, OBJECT* pObj) {
315  return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj));
316  }
318  virtual STATUS registerObject(OBJECT* parent, int obj, OBJECT* pObj) {
319  return _CALL(m_current.dataProvider, registerObject, (parent, obj, pObj));
320  }
323  return _CALL(m_current.dataProvider, unregisterObject, (path));
324  }
326  virtual STATUS unregisterObject(CSTR& parent, CSTR& obj) {
327  return _CALL(m_current.dataProvider, unregisterObject, (parent, obj));
328  }
330  virtual STATUS unregisterObject(CSTR& parent, int obj) {
331  return _CALL(m_current.dataProvider, unregisterObject, (parent, obj));
332  }
334  virtual STATUS unregisterObject(OBJECT* pObj) {
335  return _CALL(m_current.dataProvider, unregisterObject, (pObj));
336  }
339  return _CALL(m_current.dataProvider, unregisterObject, (pObj, path));
340  }
342  virtual STATUS unregisterObject(OBJECT* pObj, int item ) {
343  return _CALL(m_current.dataProvider, unregisterObject, (pObj, item));
344  }
346  virtual STATUS retrieveObject(IRegistry* parent, CSTR& path, OBJECT*& pObj ) {
347  return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj));
348  }
350  virtual STATUS retrieveObject(CSTR& path, OBJECT*& pObj) {
351  return _CALL(m_current.dataProvider, retrieveObject, (path, pObj));
352  }
354  virtual STATUS retrieveObject(CSTR& parent, CSTR& path, OBJECT*& pObj ) {
355  return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj));
356  }
358  virtual STATUS retrieveObject(CSTR& parent, int item, OBJECT*& pObj) {
359  return _CALL(m_current.dataProvider, retrieveObject, (parent, item, pObj));
360  }
362  virtual STATUS retrieveObject(OBJECT* parent, CSTR& path, OBJECT*& pObj ) {
363  return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj));
364  }
366  virtual STATUS retrieveObject(OBJECT* parent, int item, OBJECT*& pObj ) {
367  return _CALL(m_current.dataProvider, retrieveObject, (parent, item, pObj));
368  }
370  virtual STATUS findObject(CSTR& path, OBJECT*& pObj) {
371  return _CALL(m_current.dataProvider, retrieveObject, (path, pObj));
372  }
374  virtual STATUS findObject(IRegistry* parent, CSTR& path, OBJECT*& pObj) {
375  return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj));
376  }
378  virtual STATUS findObject(CSTR& parent, CSTR& path, OBJECT*& pObj) {
379  return _CALL(m_current.dataProvider, retrieveObject, (parent, path, pObj));
380  }
382  virtual STATUS findObject(CSTR& parent, int item, OBJECT*& pObject ) {
383  return _CALL(m_current.dataProvider, findObject, (parent, item, pObject));
384  }
386  virtual STATUS findObject(OBJECT* parent, CSTR& path, OBJECT*& pObject) {
387  return _CALL(m_current.dataProvider, findObject, (parent, path, pObject));
388  }
390  virtual STATUS findObject(OBJECT* parent, int item, OBJECT*& pObject) {
391  return _CALL(m_current.dataProvider, findObject, (parent, item, pObject));
392  }
394  virtual STATUS linkObject(IRegistry* from, CSTR& objPath, OBJECT* to) {
395  return _CALL(m_current.dataProvider, linkObject, (from, objPath, to));
396  }
398  virtual STATUS linkObject(CSTR& from, CSTR& objPath, OBJECT* to) {
399  return _CALL(m_current.dataProvider, linkObject, (from, objPath, to));
400  }
402  virtual STATUS linkObject(OBJECT* from, CSTR& objPath, OBJECT* to) {
403  return _CALL(m_current.dataProvider, linkObject, (from, objPath, to));
404  }
406  virtual STATUS linkObject(CSTR& fullPath, OBJECT* to) {
407  return _CALL(m_current.dataProvider, linkObject, (fullPath, to));
408  }
410  virtual STATUS unlinkObject(IRegistry* from, CSTR& objPath) {
411  return _CALL(m_current.dataProvider, unlinkObject, (from, objPath));
412  }
414  virtual STATUS unlinkObject(CSTR& from, CSTR& objPath) {
415  return _CALL(m_current.dataProvider, unlinkObject, (from, objPath));
416  }
418  virtual STATUS unlinkObject(OBJECT* from, CSTR& objPath) {
419  return _CALL(m_current.dataProvider, unlinkObject, (from, objPath));
420  }
423  return _CALL(m_current.dataProvider, unlinkObject, (path));
424  }
426  virtual STATUS updateObject(IRegistry* pDirectory ) {
427  return _CALL(m_current.dataProvider, updateObject, (pDirectory));
428  }
431  return _CALL(m_current.dataProvider, updateObject, (path));
432  }
434  virtual STATUS updateObject(OBJECT* pObj ) {
435  return _CALL(m_current.dataProvider, updateObject, (pObj));
436  }
438  virtual STATUS updateObject(CSTR& parent, CSTR& updatePath ) {
439  return _CALL(m_current.dataProvider, updateObject, (parent, updatePath));
440  }
442  virtual STATUS updateObject(OBJECT* parent, CSTR& updatePath) {
443  return _CALL(m_current.dataProvider, updateObject, (parent, updatePath));
444  }
445 
447  virtual STATUS create(CSTR& nam, CSTR& typ) {
448  IInterface* pPartition = 0;
449  return create(nam, typ, pPartition);
450  }
451 
453  virtual STATUS create(CSTR& nam, CSTR& typ, IInterface*& pPartition) {
454  STATUS sc = get(nam, pPartition);
455  if ( !sc.isSuccess() ) {
456  Gaudi::Utils::TypeNameString item(typ);
458  SmartIF<IService>& isvc = serviceLocator()->service(typ);
459  if (isvc.isValid()) {
460  SmartIF<IDataManagerSvc> dataMgr(isvc);
461  SmartIF<IDataProviderSvc> dataProv(isvc);
462  if ( dataMgr.isValid() && dataProv.isValid() ) {
463  Partition p;
464  p.name = nam;
465  p.dataManager = dataMgr;
466  p.dataProvider = dataProv;
467  p.dataManager->addRef();
468  p.dataProvider->addRef();
470  return STATUS::SUCCESS;
471  }
472  else {
473  // Error
474  return NO_INTERFACE;
475  }
476  }
477  else {
478  // Error
479  return NO_INTERFACE;
480  }
481  }
482  return PARTITION_EXISTS;
483  }
484 
486  virtual STATUS drop(CSTR& nam) {
488  if ( i != m_partitions.end() ) {
489  if ( (*i).second.dataManager == m_current.dataManager ) {
490  m_current = Partition();
491  }
492  (*i).second.dataManager->clearStore().ignore();
493  (*i).second.dataProvider->release();
494  (*i).second.dataManager->release();
495  m_partitions.erase(i);
496  return STATUS::SUCCESS;
497  }
498  return PARTITION_NOT_PRESENT;
499  }
500 
502  virtual STATUS drop(IInterface* pPartition) {
503  SmartIF<IDataProviderSvc> provider(pPartition);
504  if ( provider.isValid() ) {
506  for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
507  if ( (*i).second.dataProvider == provider ) {
508  (*i).second.dataManager->clearStore().ignore();
509  (*i).second.dataProvider->release();
510  (*i).second.dataManager->release();
511  m_partitions.erase(i);
512  return STATUS::SUCCESS;
513  }
514  }
515  return PARTITION_NOT_PRESENT;
516  }
517  return NO_INTERFACE;
518  }
519 
521  virtual STATUS activate(CSTR& nam) {
523  if ( i != m_partitions.end() ) {
524  m_current = (*i).second;
525  return STATUS::SUCCESS;
526  }
527  m_current = Partition();
528  return PARTITION_NOT_PRESENT;
529  }
530 
532  virtual STATUS activate(IInterface* pPartition) {
533  SmartIF<IDataProviderSvc> provider(pPartition);
534  m_current = Partition();
535  if ( provider ) {
537  for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
538  if ( (*i).second.dataProvider == provider ) {
539  m_current = (*i).second;
540  return STATUS::SUCCESS;
541  }
542  }
543  return PARTITION_NOT_PRESENT;
544  }
545  return NO_INTERFACE;
546  }
547 
549  virtual STATUS get(CSTR& nam, IInterface*& pPartition) const {
551  if ( i != m_partitions.end() ) {
552  pPartition = (*i).second.dataProvider;
553  return STATUS::SUCCESS;
554  }
555  pPartition = 0;
556  return PARTITION_NOT_PRESENT;
557  }
558 
560  virtual StatusCode activePartition(std::string& nam, IInterface*& pPartition) const {
561  if ( m_current.dataProvider ) {
562  nam = m_current.name;
563  pPartition = m_current.dataProvider;
564  return STATUS::SUCCESS;
565  }
566  nam = "";
567  pPartition = 0;
568  return NO_ACTIVE_PARTITION;
569  }
570 
572  MsgStream log(msgSvc(), name());
573  // Attach address creator facility
575  if (!sc.isSuccess()) {
576  log << MSG::ERROR
577  << "Failed to retrieve data loader "
578  << "\"" << m_loader << "\"" << endmsg;
579  return sc;
580  }
581  IConversionSvc* dataLoader = 0;
582  // Attach data loader facility
583  sc = service(m_loader, dataLoader, true);
584  if (!sc.isSuccess()) {
585  log << MSG::ERROR << "Failed to retrieve data loader "
586  << "\"" << m_loader << "\"" << endmsg;
587  return sc;
588  }
589  sc = setDataLoader(dataLoader);
590  dataLoader->release();
591  if (!sc.isSuccess()) {
592  log << MSG::ERROR << "Failed to set data loader "
593  << "\"" << m_loader << "\"" << endmsg;
594  return sc;
595  }
596  return sc;
597  }
598 
602  m_addrCreator = 0;
603  m_dataLoader = 0;
604  return STATUS::SUCCESS;
605  }
606 
608  virtual STATUS initialize() {
609  // Nothing to do: just call base class initialisation
611  if ( !sc.isSuccess() ) {
612  return sc;
613  }
614  sc = makePartitions();
615  if (!sc.isSuccess()) {
616  MsgStream log(msgSvc(), name());
617  log << MSG::ERROR << "Failed to connect to all store partitions." << endmsg;
618  return sc;
619  }
620  return attachServices();
621  }
622 
624  virtual STATUS reinitialize() {
626  MsgStream log(msgSvc(), name());
627  if (!sc.isSuccess()) {
628  log << MSG::ERROR << "Enable to reinitialize base class"
629  << endmsg;
630  return sc;
631  }
632  detachServices();
633  sc = attachServices();
634  if ( !sc.isSuccess() ) {
635  log << MSG::ERROR << "Failed to attach necessary services." << endmsg;
636  return sc;
637  }
638  sc = makePartitions();
639  if (!sc.isSuccess()) {
640  log << MSG::ERROR << "Failed to connect to store partitions." << endmsg;
641  return sc;
642  }
643  // return
644  return STATUS::SUCCESS;
645  }
646 
648  virtual STATUS finalize() {
649  setDataLoader(0).ignore();
650  clearStore().ignore();
652  m_current = Partition();
653  detachServices();
654  return Service::finalize();
655  }
656 
657 
658 //protected:
659 
662  : base_class(name,svc), m_rootCLID(110), m_rootName("/Event"),
664  {
665  m_dataLoader = 0;
666  declareProperty("RootCLID", m_rootCLID);
667  declareProperty("RootName", m_rootName);
668  declareProperty("Partitions", m_partitionDefs);
669  declareProperty("DataLoader", m_loader="EventPersistencySvc");
670  declareProperty("DefaultPartition", m_defaultPartition="Default");
671  }
672 
674  virtual ~MultiStoreSvc() {
675  setDataLoader(0).ignore();
676  resetPreLoad().ignore();
677  clearStore().ignore();
679  }
680 
683  STATUS iret = STATUS::SUCCESS;
686  switch ( m_root.type ) {
687  case address_type:
688  if ( m_root.root.address ) {
689  ADDRESS* pAdd = 0;
690  ADDRESS* p = m_root.root.address;
692  p->clID(),
693  p->par(),
694  p->ipar(),
695  pAdd);
696  if ( sc.isSuccess() ) {
697  sc = (*i).second.dataManager->setRoot(m_root.path, pAdd);
698  }
699  }
700  break;
701  case object_type:
702  if ( m_root.root.object ) {
703  if ( m_root.root.object->clID() == CLID_DataObject ) {
704  DataObject* pObj = new DataObject();
705  sc = (*i).second.dataManager->setRoot(m_root.path, pObj);
706  }
707  }
708  break;
709  default:
710  sc = STATUS::FAILURE;
711  break;
712  }
713  if ( !sc.isSuccess() ) {
714  iret = sc;
715  }
716  }
717  return iret;
718  }
719 
723  for(i=m_partitions.begin(); i != m_partitions.end(); ++i) {
724  (*i).second.dataManager->clearStore().ignore();
725  (*i).second.dataProvider->release();
726  (*i).second.dataManager->release();
727  }
729  return STATUS::SUCCESS;
730  }
731 
734  std::string typ, nam;
737  for(j=m_partitionDefs.begin(); j != m_partitionDefs.end(); ++j) {
738  Tokenizer tok(true);
740  tok.analyse(*j, " ", "", "", "=", "'", "'");
741  for(i = tok.items().begin(); i != tok.items().end(); i++ ) {
742  CSTR& t = (*i).tag();
743  CSTR& v = (*i).value();
744  switch( ::toupper(t[0]) ) {
745  case 'N':
746  nam = v;
747  break;
748  case 'T':
749  typ = v;
750  break;
751  }
752  }
753  STATUS sc = create(nam, typ);
754  if ( !sc.isSuccess() ) {
755  return sc;
756  }
757  else if ( !m_defaultPartition.length() ) {
758  m_defaultPartition = nam;
759  }
760  }
761  return STATUS::SUCCESS;
762  }
763 };
764 
765 // Instantiation of a static factory class used by clients to create
766 // instances of this service

Generated at Wed Nov 28 2012 12:17:10 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004