Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

DbGenericConverter.cpp

Go to the documentation of this file.
00001 //====================================================================
00002 //      DbGenericConverter implementation
00003 //--------------------------------------------------------------------
00004 //
00005 //      Package    : System ( The LHCb Offline System)
00006 //
00007 //  Description: Generic Db data converter
00008 //
00009 //  Object layout:
00010 //  ------------------------------------------------------------
00011 //  Base Object: DataObject's Leafs
00012 //  Base Object: DataObject's Links
00013 //  ------------------------------------------------------------
00014 //  Contained  links
00015 //  Identified links
00016 //  Object data
00017 //
00018 //  I know that this code lokks VERY ugly. However, since a major
00019 //  part of the data consists out of contained or identified links
00020 //  between objects, this part was tried to be optimized.
00021 //
00022 //
00023 //
00024 //      Author     : M.Frank
00025 //====================================================================
00026 #define DBCNV_DBGENERICCONVERTER_CPP
00027 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiDb/src/Base/DbGenericConverter.cpp,v 1.1.1.1 2001/04/18 21:13:35 tlindner Exp $
00028 
00029 #include "GaudiDb/DbOOMs.h"
00030 #include "GaudiDb/IOODataBase.h"
00031 #include "GaudiDb/DbContainer.h"
00032 #include "GaudiDb/DbDefObject.h"
00033 #include "GaudiDb/DbGenericConverter.h"
00034 
00035 #include "GaudiKernel/StreamBuffer.h"
00036 #include "GaudiKernel/ContainedObject.h"
00037 #include "GaudiKernel/ObjectContainerBase.h"
00038 
00039 inline bool __WRITE__(char mask, StreamBuffer& buf, long item)   {
00040   switch(mask)    {
00041   case 1:  buf << char (item);   return true;
00042   case 2:  buf << short(item);   return true;
00043   case 3:  buf << long (item);   return true;
00044   default:                       return false;
00045   }
00046 }
00047 
00048 inline bool __READ__(char mask, StreamBuffer& buf, long& item)   {
00049   switch(mask)    {
00050   case 1:  { char  ___i; buf >> ___i; item = ___i;  return true; }
00051   case 2:  { short ___i; buf >> ___i; item = ___i;  return true; }
00052   case 3:  {             buf >> item;               return true; }
00053   default: {                                       return false; }
00054   }
00055 }
00056 
00058 DbGenericConverter::DbGenericConverter(const CLID& clid, IOODataBase* db, ISvcLocator* svc)
00059 : DbBaseConverter( clid, db, svc )
00060 {
00061   std::string typName = System::typeinfoName(typeid(DbDefObject));
00062   m_type = db->typeInfo(typName);
00063 }
00064 
00066 DbGenericConverter::~DbGenericConverter()     {
00067 }
00068 
00070 dbHandle<DbObject> DbGenericConverter::createPersistent(dbHandle<DbContainer>& cntH)  {
00071   dbHandle<DbObject> handle = new(cntH, *m_type) DbDefObject();
00072   return handle;
00073 }
00074 
00076 void DbGenericConverter::clearBuffers(dbHandle<DbDefObject>& objH )   {
00077   StreamBuffer& objBuf = objH->streamBuffer();
00078   StreamBuffer& lnkBuf = objH->linkBuffer();
00079   // Setup object data buffer
00080   objBuf.setMode(StreamBuffer::WRITING);
00081   objBuf.setBuffPointer(0);
00082   // Setup link buffer
00083   lnkBuf.setMode(StreamBuffer::WRITING);
00084   lnkBuf.setBuffPointer(0);
00085 }
00086 
00088 StatusCode DbGenericConverter::beginPersistentUpdate( DefHandle& objH, const DataObject* /* pObject */ )   {
00089   clearBuffers(objH);
00090   return StatusCode::SUCCESS;
00091 }
00092 
00094 StatusCode DbGenericConverter::endPersistentUpdate( DefHandle& objH, const DataObject* pObject)   {
00095   typedef StreamBuffer::ContainedLinks        CLinks;
00096   typedef StreamBuffer::IdentifiedLinks       ILinks;
00097   StreamBuffer& objBuf = objH->streamBuffer();
00098   CLinks& c_links = objBuf.containedLinks();
00099   ILinks& i_links = objBuf.identifiedLinks();
00100 
00101   // First serialize the entire object
00102   objH->setObjSize (objBuf.buffPointer());
00103   if ( c_links.size() > 0 || i_links.size() > 0 )   {
00104     StreamBuffer& linkBuf = objH->linkBuffer();
00105     CLinks::iterator i, end;
00106     ILinks::iterator j;
00107     DataObject* pD;
00108     const long INVALID = StreamBuffer::INVALID;
00109     long linkMax = 0, hintMax = 0, num, k;
00110     char linkMask, hintMask;
00111     num = (i_links.size() > c_links.size()) ? i_links.size() : c_links.size();
00112     long* hints = new long[num];
00113     long* links = new long[c_links.size()];
00114     // Need to protect memory allocation against failures!
00115     try   {
00116       // Second: Serialize all links to contained objects (type ContainedObject)
00117       const ObjectContainerBase* last_par = 0;
00118       long last_hint = INVALID;
00119       std::string path;
00120       for (num = c_links.size()-1, i = c_links.begin(), end = c_links.end(); i != end; i++ )    {
00121         hints[num] = links[num] = INVALID;
00122         if ( 0 != (*i).first && 0 != (*i).first->parent() )    {
00123           const ObjectContainerBase* par = (*i).first->parent();
00124           if ( par != last_par )    {
00125             last_par = par;
00126             path = par->fullpath();
00127             last_hint = pObject->addLink(path, par);
00128             if ( last_hint > hintMax ) hintMax = last_hint;
00129           }
00130           hints[num] = last_hint;
00131           links[num] = last_par->distance((*i).first);
00132           if ( links[num] > linkMax ) linkMax = links[num];
00133         }
00134         num--;
00135       }
00136       num  = c_links.size();
00137       (linkBuf) << num;
00138       if ( num > 0 )   {
00139         hintMask = (hintMax < SCHAR_MAX) ? 1 : (hintMax < SHRT_MAX) ? 2 : 3;
00140         linkMask = (linkMax < SCHAR_MAX) ? 1 : (linkMax < SHRT_MAX) ? 2 : 3;
00141         (linkBuf) << hintMask << linkMask;
00142         for ( k = 0; k < num; k++ )   {
00143           if ( !__WRITE__(hintMask, linkBuf, hints[k]) )
00144             goto Error;
00145           if ( !__WRITE__(linkMask, linkBuf, links[k]) )
00146             goto Error;
00147         }
00148       }
00149       // Second: Serialize all links to identified objects (type DataObject) 
00150       for (j = i_links.begin(), num = 0; j != i_links.end(); j++)    {
00151         pD = (*j).first;
00152         hints[num] = (0 == pD) ? INVALID : pObject->addLink(pD->fullpath(), pD);
00153         if ( hints[num] > hintMax ) hintMax = hints[num];
00154         num++;
00155       }
00156       num = i_links.size();
00157       (linkBuf) << num;
00158       if ( num > 0 )    {
00159         hintMask = (hintMax < SCHAR_MAX) ? 1 : (hintMax < SHRT_MAX) ? 2 : 3;
00160         (linkBuf) << hintMask;
00161         for ( k = 0; k < num; k++ )   {
00162           if ( !__WRITE__(hintMask, linkBuf, hints[k]) )
00163             goto Error;
00164         }
00165       }
00166       goto Done;
00167     }
00168     catch(...)    {
00169     }
00170   Error:
00171       delete links;
00172       delete hints;
00173       return StatusCode::FAILURE;
00174   Done:
00175     delete links;
00176     delete hints;
00177   }
00178   return StatusCode::SUCCESS;
00179 }
00180 
00182 StatusCode DbGenericConverter::doPersistentUpdate( dbHandle<DbDefObject>& objH, const DataObject* pObject)    {
00183   StreamBuffer& objBuf = objH->streamBuffer();
00184   objBuf << pObject->clID();
00185   pObject->serialize(objBuf);
00186   return StatusCode::SUCCESS;
00187 }
00188 
00190 StatusCode DbGenericConverter::beginTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject)    {
00191   ObjectContainerBase* pCont;
00192   DataObject::Link* link;
00193   ContainedObject* pContained;
00194   StreamBuffer& objBuf = objH->streamBuffer();
00195 
00196   objBuf.reserve(objH->objSize());
00197   objBuf.setMode(StreamBuffer::READING);
00198   objBuf.setBuffPointer(0);
00199   if ( objH->linkSize() > 0 )   {
00200     StreamBuffer& linkBuf = objH->linkBuffer();
00201     const long INVALID = StreamBuffer::INVALID;
00202     long i, hint_id, link_id, numContd, numIdent;
00203     char linkMask, hintMask;
00204     linkBuf.setMode(StreamBuffer::READING);
00205     linkBuf.reserve(objH->linkSize());
00206     linkBuf.setBuffPointer(0);
00207     linkBuf >> numContd;
00208     if ( numContd > 0 )   {
00209       (linkBuf) >> hintMask >> linkMask;
00210       objBuf.containedLinks().reserve ( numContd );
00211       // First: de-serialize links to contained objects
00212       for ( i = 0; i < numContd; i++ )      {
00213         if ( !__READ__(hintMask, linkBuf, hint_id) || 
00214              !__READ__(linkMask, linkBuf, link_id) ) 
00215              goto Error;
00216         if ( INVALID == link_id || INVALID == hint_id )   {
00217           objBuf.addContainedLink(0, INVALID, INVALID);
00218         }
00219         else  {
00220           link = pObject->symLink(hint_id);
00221           DataObject* linkObj = (link) ? link->object() : 0;
00222           pContained = 0;
00223           if ( 0 != linkObj )    {
00224             try   {
00225               pCont = dynamic_cast<ObjectContainerBase*>(linkObj);
00226               if ( 0 != pCont )    {
00227                 pContained = pCont->containedObject(link_id);
00228               }
00229             }
00230             catch(...)    {
00231             }
00232           }
00233           objBuf.addContainedLink(pContained, hint_id, link_id);
00234         }
00235       }
00236     }
00237     linkBuf >> numIdent;
00238     if ( numIdent > 0 )   {
00239       (linkBuf) >> hintMask;
00240       objBuf.identifiedLinks().reserve( numIdent );
00241       // Second: de-serialize links to identified objects
00242       for ( i = 0; i < numIdent; i++ )      {
00243         if ( !__READ__(hintMask, linkBuf, hint_id) )
00244           goto Error;
00245         if ( INVALID == hint_id )   {
00246           objBuf.addIdentifiedLink(0, INVALID);
00247         }
00248         else    {
00249           link = pObject->symLink(hint_id);
00250           objBuf.addIdentifiedLink((link) ? link->object() : 0, hint_id);
00251         }
00252       }
00253     }
00254   }
00255   return StatusCode::SUCCESS;
00256 Error:
00257   return StatusCode::FAILURE;
00258 }
00259 
00261 StatusCode DbGenericConverter::endTransientUpdate( dbHandle<DbDefObject>& /* objH */ , DataObject* /* pObject */ )    {
00262   return StatusCode::SUCCESS;
00263 }
00264 
00266 StatusCode DbGenericConverter::doTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject)    {
00267   if ( 0 != pObject && objH.isValid() )   {
00268     StreamBuffer& s = objH->streamBuffer();
00269     CLID clid;
00270     s >> clid;
00271     if ( clid == pObject->clID() )    {
00272       pObject->serialize(s);
00273       return StatusCode::SUCCESS;
00274     }
00275   }
00276   return StatusCode::FAILURE;
00277 }

Generated at Wed Nov 21 12:22:19 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000