Gaudi Framework, version v23r0

Home   Generated: Mon Jan 30 2012
Public Member Functions | Protected Member Functions | Private Types | Private Attributes

GaudiMP::TESSerializer Class Reference

#include <TESSerializer.h>

Inheritance diagram for GaudiMP::TESSerializer:
Inheritance graph
[legend]
Collaboration diagram for GaudiMP::TESSerializer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 TESSerializer (IDataProviderSvc *svc, IAddressCreator *ac)
 Constructor.
void dumpBuffer (TBufferFile &)
 Dump TES contents listed in m_itemList/m_optItemList to a TBufferFile.
void loadBuffer (TBufferFile &)
 Rebuild TES from items in a TBufferFile.
void addItem (const std::string &path)
 add an item to the TESSerializer's list (notation)
void addOptItem (const std::string &path)
 add an item to the TESSerializer's optional list (notation)
bool analyse (IRegistry *dir, int level)
 Analysis callback.
void checkItems ()
 print out the contents of m_itemList and m_optItemList (std::cout)
virtual ~TESSerializer ()

Protected Member Functions

void addItem (Items &itms, const std::string &descriptor)
 Add item to the list of items to be serialized (notation)
DataStoreItemfindItem (const std::string &path)
 Find single item identified by its path (exact match)

Private Types

typedef std::vector
< DataStoreItem * > 
Items
typedef std::vector< std::stringItemNames
typedef std::vector< DataObject * > Objects

Private Attributes

IDataProviderSvcm_TES
 TES pointer.
IDataManagerSvcm_TESMgr
 TES pointer.
ItemNames m_itemNames
 Vector of item names.
Items m_itemList
 Vector of items to be saved to this stream (DataStoreItem ptrs)
ItemNames m_optItemNames
 Vector of item names (std::strings)
Items m_optItemList
 Vector of optional items to be saved to this stream (DataStoreItem ptrs)
DataStoreItemm_currentItem
 Current item while traversing the TES tree.
Objects m_objects
 Selected list of Objects to be serialized (DataObject ptrs)
std::map< std::string, TClass * > m_classMap
 Map of gROOT class information.
bool m_verifyItems
 Boolean Flag as used by GaudiSvc/PersistencySvc/OutputStreamer.
bool m_strict
 Boolean Flag used to determine error tolerance.
IAddressCreatorm_addressCreator
 IAddress Creator for Opaque Addresses.

Detailed Description

Definition at line 32 of file TESSerializer.h.


Member Typedef Documentation

Definition at line 34 of file TESSerializer.h.

Definition at line 33 of file TESSerializer.h.

Definition at line 35 of file TESSerializer.h.


Constructor & Destructor Documentation

GaudiMP::TESSerializer::TESSerializer ( IDataProviderSvc svc,
IAddressCreator ac 
)

Constructor.

Definition at line 68 of file TESSerializer.cpp.

  : m_TES(svc)
{
  m_TESMgr = dynamic_cast<IDataManagerSvc*>(svc);
  m_addressCreator = ac;
  m_verifyItems = false;
  m_strict      = false;
}
virtual GaudiMP::TESSerializer::~TESSerializer (  ) [inline, virtual]

Definition at line 58 of file TESSerializer.h.

{}

Member Function Documentation

void GaudiMP::TESSerializer::addItem ( const std::string path )

add an item to the TESSerializer's list (notation)

Add item to serialization list; ie append to std::vector of DataStoreItems.

Definition at line 376 of file TESSerializer.cpp.

                                                          {
  // #notation supported
  addItem( m_itemList, path );
}
void GaudiMP::TESSerializer::addItem ( Items itms,
const std::string descriptor 
) [protected]

Add item to the list of items to be serialized (notation)

Add item to output streamer list (protected)

Definition at line 329 of file TESSerializer.cpp.

                                                                             {
  // supports # notation
  int level = 0;

  std::string slevel;
  std::string obj_path;

  // Process the incoming string
  size_t sep = descriptor.rfind("#");
  if (sep > descriptor.length()) {
    // invalid sep case (# not found in string)
    obj_path = descriptor;
    slevel   = "1";
  } else {
    // valid sep case
    obj_path = descriptor.substr(0,sep);
    slevel   = descriptor.substr(sep+1);
  }

  // Convert the level string to an integer
  if ( slevel == "*" )  {
    level = 9999999;
  }
  else   {
    level = atoi(slevel.c_str());
  }

  // Are we verifying?
  if ( m_verifyItems )  {
    size_t idx = obj_path.find("/",1);
    while(idx != std::string::npos)  {
      std::string sub_item = obj_path.substr(0,idx);
      if ( 0 == findItem(sub_item) )   {
        cout << "... calling addItem with arg : " << sub_item << endl;
        addItem(itms, sub_item);
      }
      idx = obj_path.find("/",idx+1);
    }
  }
  DataStoreItem* item = new DataStoreItem(obj_path, level);
  //cout << "Adding TESSerializer item " << item->path()
  //   << " with " << item->depth()
  //   << " level(s)." << endl;
  itms.push_back( item );
}
void GaudiMP::TESSerializer::addOptItem ( const std::string path )

add an item to the TESSerializer's optional list (notation)

Add optional item to output streamer list.

Definition at line 382 of file TESSerializer.cpp.

                                                             {
  // #notation supported
  addItem( m_optItemList, path);
}
bool GaudiMP::TESSerializer::analyse ( IRegistry dir,
int  level 
) [virtual]

Analysis callback.

Implements IDataStoreAgent.

Definition at line 57 of file TESSerializer.cpp.

                                                              {
  if ( level < m_currentItem->depth() )   {
    if ( dir->object() != 0 )   {
      m_objects.push_back(dir->object());
      return true;
    }
  }
  return false;
}
void GaudiMP::TESSerializer::checkItems (  )

print out the contents of m_itemList and m_optItemList (std::cout)

Uses cout to print the contents of the mandatory and optional item lists.

Definition at line 388 of file TESSerializer.cpp.

                                        {
  cout << "TESSerializer m_itemList : " << m_itemList.size() << " Items"<< endl;
  for(Items::const_iterator i=m_itemList.begin(); i != m_itemList.end(); ++i)  {
    cout << "\tItem : " << (*i)->path() << endl;
  }
  cout << "TESSerializer m_optItemList : " << m_optItemList.size() << " Items" << endl;
  for(Items::const_iterator i=m_optItemList.begin(); i != m_optItemList.end(); ++i)  {
    cout << "\tItem : " << (*i)->path() << endl;
  }
}
void GaudiMP::TESSerializer::dumpBuffer ( TBufferFile &  buffer )

Dump TES contents listed in m_itemList/m_optItemList to a TBufferFile.

Serialize contents of TES to a TBufferFile.

Definition at line 78 of file TESSerializer.cpp.

                                                         {
  //
  //  Write all valid objects to the TBufferFile provided in the argument
  //  As objects are collected, the member variable m_classMap is filled
  //  with ROOT Class data, and is kept by the Serializer for future
  //  reference
  //
  //  @paramTBufferFile& buffer : TBufferFile passed by reference
  //          Cannot be declared inside the method, as repeated calls
  //          can cause confusion and buffer wiping.
  //
  StatusCode status;
  DataObject* obj;

  // Clear current selection
  m_objects.erase(m_objects.begin(), m_objects.end());

  // Traverse the tree and collect the requested objects
  for ( Items::iterator i = m_itemList.begin(); i != m_itemList.end(); i++ )    {
    m_currentItem = (*i);
    // cout << "Retrieving Mandatory Object : " << m_currentItem->path() << endl;
    status = m_TES->retrieveObject(m_currentItem->path(), obj);
    if ( status.isSuccess() )  {
      m_TESMgr->traverseSubTree(obj, this);
    }
    else  {
      string text("WARNING: Cannot retrieve TES object(s) for serialisation: ");
      text += m_currentItem->path();
      if ( m_strict ) {
        throw GaudiException(text + m_currentItem->path(), "", status);
      } else {
        cout << text << endl;
        // return StatusCode::FAILURE;
      }
    }
  }
  // Traverse the tree and collect the requested objects (tolerate missing items here)
  for ( Items::iterator i = m_optItemList.begin(); i != m_optItemList.end(); i++ )    {
    m_currentItem = (*i);
    // cout << "Retrieving Optional Object : " << m_currentItem->path() << endl;
    status= m_TES->retrieveObject(m_currentItem->path(), obj);
    if ( status.isSuccess() )  {
      m_TESMgr->traverseSubTree(obj, this);
    }
  }

  // cout << "TESSerializer : Beginning loop to write to TBufferFile for nObjects : " << m_objects.size() << endl;
  buffer.WriteInt(m_objects.size());

  for(Objects::iterator i = m_objects.begin(); i != m_objects.end(); ++i) {
    DataObject* pObj = (*i);    /* define pointer !pObj! to a data object */
    DataObjectPush p(pObj);             /* add the data object to the list... */

    // We build a map so gROOT has to access the whole class database as little as possible
    TClass* cl;                                                 /* announce a TClass */
    const type_info& objClass = typeid(*pObj);                  /* get the type of the data object */
    // cout << "TES Object : " << pObj->registry()->identifier() << endl;
    string objClassName = System::typeinfoName(objClass);       /* and then get the descriptive string from System */

    /* First go   : populate the class map
       Subsequent : refer to class map     */
    if (m_classMap[objClassName])   {
      cl=m_classMap[objClassName];
    } else {
      /* Map new object : pull the class name from the objects c_str() method */
      const char* clName = objClassName.c_str();
      /* Find the relevant Tclass (cl) in gROOT, and fill the map entry */
      cl = gROOT->GetClass(clName);
      m_classMap[objClassName]=cl;
    }

    /* Now, check if clname was valid... */
    if (cl==0){
      if ( m_strict ) {
        throw GaudiException("gROOT->GetClass cannot find clName", objClassName, StatusCode::FAILURE);
      } else  {
        cout << "WARNING: gROOT->GetClass fails for clname : "
            << objClassName.c_str() << endl;
        cout << "WARNING: Disregarding " << objClassName.c_str()
            << "erasing from object list" << endl;
        m_objects.erase( i );
        continue;
      }
    }

    // write object to buffer in order location-name-object
    std::string loc=pObj->registry()->identifier();
    buffer.WriteString(loc.c_str());
    buffer.WriteString(cl->GetName());
    cl->Streamer(pObj,buffer);

    /* take care of links */
    LinkManager* linkMgr = pObj->linkMgr();
    int numLinks = linkMgr->size();
    buffer.WriteInt(numLinks);
    // now write each link
    for (int it = 0; it != numLinks; it++)        {
      const string& link = linkMgr->link(it)->path();
      buffer.WriteString(link.c_str());
    }

    // now do the thing with the opaqueAddress
    // to go from string->object when recovering, will need svc_type, and clid, aswell as the string version
    IOpaqueAddress* iop = pObj->registry()->address();
    if (iop) {
      buffer.WriteInt(1);
      const string * par = iop->par();
      long svcType       = iop->svcType();
      long clid          = iop->clID();
      buffer.WriteLong(svcType);
      buffer.WriteLong(clid);
      buffer.WriteString(par->c_str());
    } else {
      buffer.WriteInt(0);
    }
    // object complete, continue in for-loop
  }

  // Final Actions
  // Write the End Flag, to avoid potential SegFaults on loadBuffer
  buffer.WriteString(SERIALIZER_END);
  // return StatusCode::SUCCESS;
}
DataStoreItem * GaudiMP::TESSerializer::findItem ( const std::string path ) [protected]

Find single item identified by its path (exact match)

Definition at line 401 of file TESSerializer.cpp.

                                                     {
  for(Items::const_iterator i=m_itemList.begin(); i != m_itemList.end(); ++i)  {
    if ( (*i)->path() == path )  return (*i);
  }
  for(Items::const_iterator j=m_optItemList.begin(); j != m_optItemList.end(); ++j)  {
    if ( (*j)->path() == path )  return (*j);
  }
  return 0;
}
void GaudiMP::TESSerializer::loadBuffer ( TBufferFile &  buffer )

Rebuild TES from items in a TBufferFile.

Reconstruct the TES from a given TBufferFile.

The next is equivalent to ReadObjectAny(cl) except of the 'magic!!'

Definition at line 203 of file TESSerializer.cpp.

                                                         {

  // reverse mechanism of dumps
  // buffer is: length of DataObjects vector
  //            location string
  //            type name string
  //            the object itself
  //            count of links
  //            list of links (conditional on count)
  //            flag indicating Opaque Address presence
  //            Opaque Address svcType (conditional on flag)
  //            Opaque Address clID    (conditional on flag)
  //            Opaque Address par     (conditional on flag)

  int nObjects;
  // 3 StatusCodes... for :
  //   general use : registering objects : creating OpaqueAddresses
  StatusCode sc, registerStat, createAddressStat;

  // Prepare for Reading
  buffer.SetReadMode();
  buffer.SetBufferOffset();

  buffer.ReadInt(nObjects);
  for (int i=0; i<nObjects; ++i) {
    char text[4096];
    buffer.ReadString(text,sizeof(text));
    string location(text);
    if (!location.compare("EOF")) {
      /* There was an error in serialization, but the EOF
         flag marks the endpoint in any case */
      break;
    }
    buffer.ReadString(text,sizeof(text));
    TClass* cl = gROOT->GetClass(text);
    if (cl==0){
      if ( m_strict ) {
        throw GaudiException("gROOT->GetClass cannot find clName", text, StatusCode::FAILURE);
      } else {
        cout << "TESSerializer WARNING : gROOT->GetClass fails for clname : " << location.c_str() << endl;
        continue;
      }
    }

    DataObject* obj = (DataObject*)cl->New();
    DataObjectPush push(obj); // This is magic!
    cl->Streamer(obj, buffer);


    // now restore links
    if ( obj ) {
      int nlink = 0;
      LinkManager* lnkMgr = obj->linkMgr();
      buffer.ReadInt(nlink);

      for (int j = 0; j < nlink; ++j) {
        buffer.ReadString(text,sizeof(text));
        lnkMgr->addLink(text,0);
      }
    }

    // Re-register...
    registerStat = m_TES->registerObject(location, obj);
    if (registerStat.isFailure()) {
      if ( location == "/Event" ) {
        sc = m_TESMgr->setRoot(location, obj);
        if(sc.isFailure()) {
          throw GaudiException("Cannot set root at location " + location, "", sc);
        }
      }
      else {
        const char* msg = "Cannot register object at location ";
        if ( m_strict ) {
          throw GaudiException(msg + location, "", registerStat);
        } else {
          cout << "WARNING : " << msg << location << endl;
          continue;
        }
      }
    }

    // next is the opaque address information
    // create Generic Address using the info from the TBufferFile,
    // then create an IOpaqueAddress object using the Persistency Svc
    // IOpaque Address pointer (blank... pass the ref to the createAddress Fn)

    int flag(0);
    buffer.ReadInt(flag);
    // flag will be 0 or 1 to indicate OpaqueAddress Info
    if (flag==1) {
      // will need an IOpaqueAddress and its ref
      IOpaqueAddress* iop;
      IOpaqueAddress*& iopref = iop;
      // Read svcType, clID and par from buffer
      long svcType;
      buffer.ReadLong(svcType);

      long clid;
      buffer.ReadLong(clid);
      const CLID classid(clid);

      char * cp;
      cp = buffer.ReadString(text, sizeof(text));
      const string opaque(cp);
      // create Generic address
      // already have svcType, clID, par1.. just make dummy variables for par2, and ipar1 and 2
      const string& p2="";
      unsigned long ip1(0);
      unsigned long ip2(0);
      GenericAddress gadd(svcType, classid, opaque, p2, ip1, ip2);

      // now create the address
      createAddressStat = m_addressCreator->createAddress( gadd.svcType(), gadd.clID(), gadd.par(), gadd.ipar(), iopref );
      if (createAddressStat.isFailure()) {
        throw GaudiException("Failure in creating OpaqueAddress for reconstructed registry", "", createAddressStat);
      }
      // And finally, set this address
      obj->registry()->setAddress(iop);
    }
    // all done
  }
}

Member Data Documentation

IAddress Creator for Opaque Addresses.

Definition at line 92 of file TESSerializer.h.

Map of gROOT class information.

Definition at line 86 of file TESSerializer.h.

Current item while traversing the TES tree.

Definition at line 81 of file TESSerializer.h.

Vector of items to be saved to this stream (DataStoreItem ptrs)

Definition at line 75 of file TESSerializer.h.

Vector of item names.

Definition at line 73 of file TESSerializer.h.

Selected list of Objects to be serialized (DataObject ptrs)

Definition at line 83 of file TESSerializer.h.

Vector of optional items to be saved to this stream (DataStoreItem ptrs)

Definition at line 79 of file TESSerializer.h.

Vector of item names (std::strings)

Definition at line 77 of file TESSerializer.h.

Boolean Flag used to determine error tolerance.

Definition at line 90 of file TESSerializer.h.

TES pointer.

Definition at line 69 of file TESSerializer.h.

TES pointer.

Definition at line 71 of file TESSerializer.h.

Boolean Flag as used by GaudiSvc/PersistencySvc/OutputStreamer.

Definition at line 88 of file TESSerializer.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Jan 30 2012 13:53:33 for Gaudi Framework, version v23r0 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004