source: XIOS/dev/dev_olga/src/object_template_impl.hpp @ 1009

Last change on this file since 1009 was 1009, checked in by oabramkina, 7 years ago

First working version with compression by secondary servers.

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 20.7 KB
Line 
1#ifndef __XIOS_CObjectTemplate_impl__
2#define __XIOS_CObjectTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "context_client.hpp"
6#include "object_factory.hpp"
7#include "context.hpp"
8#include "buffer_in.hpp"
9#include "attribute.hpp"
10#include "event_client.hpp"
11#include "object_template.hpp"
12#include "context_client.hpp"
13#include "indent.hpp"
14#include "type_util.hpp"
15#include "message.hpp"
16#include "type.hpp"
17#include "type_util.hpp"
18#include "group_template.hpp"
19
20namespace xios
21{
22   /// ////////////////////// Définitions ////////////////////// ///
23   template <class T>
24      xios_map<StdString,
25      xios_map<StdString,
26      boost::shared_ptr<T> > > CObjectTemplate<T>::AllMapObj;
27
28   template <class T>
29      xios_map<StdString,
30      std::vector<boost::shared_ptr<T> > > CObjectTemplate<T>::AllVectObj;
31
32   template <class T>
33      xios_map<StdString,long int> CObjectTemplate<T>::GenId;
34
35   template <class T>
36      CObjectTemplate<T>::CObjectTemplate(void)
37         : CAttributeMap()
38         , CObject()
39   { /* Ne rien faire de plus */ }
40
41   template <class T>
42      CObjectTemplate<T>::CObjectTemplate(const StdString & id)
43         : CAttributeMap()
44         , CObject(id, CObjectFactory::IsGenUId<T>(id))
45   { /* Ne rien faire de plus */ }
46
47   template <class T>
48      CObjectTemplate<T>::CObjectTemplate
49         (const CObjectTemplate<T> & object, bool withAttrList, bool withId)
50         : CAttributeMap()
51         , CObject()
52   {
53      if (object.hasId() && withId)
54         this->setId(object.getId(), object.hasAutoGeneratedId());
55      ERROR("CObjectTemplate<T> construtor 3", << "Not completly implemented yet !");
56   }
57
58   template <class T>
59      CObjectTemplate<T>::~CObjectTemplate(void)
60   { /* Ne rien faire de plus */ }
61
62   ///--------------------------------------------------------------
63
64   template <class T>
65      std::vector<boost::shared_ptr<T> > &
66         CObjectTemplate<T>::GetAllVectobject(const StdString & contextId)
67   {
68      return (CObjectTemplate<T>::AllVectObj[contextId]);
69   }
70
71   //---------------------------------------------------------------
72
73   template <class T>
74      StdString CObjectTemplate<T>::toString(void) const
75   {
76      StdOStringStream oss;
77      oss << "<" << T::GetName();
78      if (this->hasId())
79         oss << " id=\"" << this->getId() << "\"";
80      oss << " " << SuperClassMap::toString() << "/>";
81      return (oss.str());
82   }
83
84   template <class T>
85      void CObjectTemplate<T>::fromString(const StdString & str)
86   {
87      ERROR("CObjectTemplate<T>::fromString(str)",
88            << "[ str = " << str << "] Not implemented yet !");
89   }
90
91   //---------------------------------------------------------------
92
93/*
94   template <class T>
95      void CObjectTemplate<T>::toBinary(StdOStream & os) const
96   {
97      SuperClassMap::toBinary(os);
98   }
99
100   template <class T>
101      void CObjectTemplate<T>::fromBinary(StdIStream & is)
102   {
103      SuperClassMap::fromBinary(is);
104   }
105*/
106
107   //---------------------------------------------------------------
108
109   template <class T>
110      void CObjectTemplate<T>::parse(xml::CXMLNode & node)
111   {
112      xml::THashAttributes attributes = node.getAttributes();
113      CAttributeMap::setAttributes(attributes);
114   }
115
116   //---------------------------------------------------------------
117
118   template <class T>
119      ENodeType CObjectTemplate<T>::getType(void) const
120   {
121      return (T::GetType());
122   }
123
124   template <class T>
125   string CObjectTemplate<T>::getName(void) const
126   {
127      return (T::GetName());
128   }
129
130   //---------------------------------------------------------------
131
132   template <class T>
133      bool CObjectTemplate<T>::hasChild(void) const
134   {
135      return (false);
136   }
137
138   //---------------------------------------------------------------
139
140   template <class T>
141      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
142   {
143      if (parent != NULL)
144         SuperClassMap::setAttributes(parent, apply);
145   }
146
147   //---------------------------------------------------------------
148
149   template <class T>
150      void CObjectTemplate<T>::ClearAllAttributes(void)
151   {
152      vector<T*> avect = CObjectTemplate<T>::getAll();
153      typename vector<T*>::iterator
154            it = avect.begin(), end = avect.end();
155
156      for (;it != end; it++)
157      {
158         CAttributeMap & amap = **it;
159         amap.clearAllAttributes();
160      }
161   }
162
163   template<typename T>
164   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes()
165   {
166     // CContextClient* client = CContext::getCurrent()->client;
167     CContext* context = CContext::getCurrent();
168
169          // Use correct context client to send message
170//     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
171     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
172     for (int i = 0; i < nbSrvPools; ++i)
173     {
174       CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
175
176       std::map<int, size_t> minimumSizes;
177
178       if (contextClientTmp->isServerLeader())
179       {
180         size_t minimumSize = 0;
181         CAttributeMap& attrMap = *this;
182         CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
183         for (; it != itE; ++it)
184         {
185           if (!it->second->isEmpty())
186           {
187             size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
188             if (size > minimumSize)
189               minimumSize = size;
190           }
191         }
192
193         if (minimumSize)
194         {
195           // Account for extra header info
196           minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
197
198           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
199           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
200             minimumSizes.insert(std::make_pair(*itRank, minimumSize));
201         }
202       }
203
204     // if (client->isServerLeader())
205     // {
206     //   size_t minimumSize = 0;
207     //   CAttributeMap& attrMap = *this;
208     //   CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
209     //   for (; it != itE; ++it)
210     //   {
211     //     if (!it->second->isEmpty())
212     //     {
213     //       size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
214     //       if (size > minimumSize)
215     //         minimumSize = size;
216     //     }
217     //   }
218
219     //   if (minimumSize)
220     //   {
221     //     // Account for extra header info
222     //     minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
223
224     //     const std::list<int>& ranks = client->getRanksServerLeader();
225     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
226     //       minimumSizes.insert(std::make_pair(*itRank, minimumSize));
227     //   }
228     // }
229
230       return minimumSizes;
231     }
232   }
233
234   template<typename T>
235   void CObjectTemplate<T>::sendAllAttributesToServer()
236   {
237     CAttributeMap& attrMap = *this;
238     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
239     for (; it != itE; ++it)
240     {
241       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second));
242     }
243   }
244
245   template<typename T>
246   void CObjectTemplate<T>::sendAllAttributesToServer(const int srvPool)
247   {
248     CAttributeMap& attrMap = *this;
249     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
250     for (; it != itE; ++it)
251     {
252       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second), srvPool);
253     }
254   }
255
256   template <class T>
257   void CObjectTemplate<T>::sendAttributToServer(const string& id)
258   {
259      CAttributeMap & attrMap = *this;
260      CAttribute* attr=attrMap[id];
261      sendAttributToServer(*attr);
262   }
263
264   template <class T>
265   void CObjectTemplate<T>::sendAttributToServer(const string& id, const int srvPool)
266   {
267      CAttributeMap & attrMap = *this;
268      CAttribute* attr=attrMap[id];
269      sendAttributToServer(*attr, srvPool);
270   }
271
272  template <class T>
273  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr)
274  {
275    CContext* context=CContext::getCurrent();
276
277     // Use correct context client to send message
278//    CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
279    if (context->hasClient)
280    {
281      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
282      for (int i = 0; i < nbSrvPools; ++i)
283      {
284        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
285        // CContextClient* contextClientTmp=context->contextClientTmp;
286
287        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
288        if (contextClientTmp->isServerLeader())
289        {
290          CMessage msg;
291//          if (context->hasServer)
292//          {
293//            StdString tmp = this->getIdServer() + "_" +boost::lexical_cast<string>(i);
294//            msg<<tmp;
295//          }
296//          else
297            msg<<this->getIdServer();
298
299          msg << attr.getName();
300          msg << attr;
301          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
302          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
303            event.push(*itRank,1,msg);
304          contextClientTmp->sendEvent(event);
305        }
306        else contextClientTmp->sendEvent(event);
307      }
308    }
309//     // if (!context->hasServer)
310//     if (context->hasClient)
311//     {
312//        CContextClient* client=context->client;
313
314//        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
315//        if (client->isServerLeader())
316//        {
317//          CMessage msg;
318// //       msg << this->getId();
319//          msg << this->getIdServer();
320//          msg << attr.getName();
321//          msg << attr;
322//          const std::list<int>& ranks = client->getRanksServerLeader();
323//          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
324//            event.push(*itRank,1,msg);
325//          client->sendEvent(event);
326//        }
327//        else client->sendEvent(event);
328//     }
329
330  }
331
332  template <class T>
333  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, const int srvPool)
334  {
335    CContext* context=CContext::getCurrent();
336    CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
337    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
338    if (contextClientTmp->isServerLeader())
339    {
340      CMessage msg;
341      msg<<this->getIdServer();
342      msg << attr.getName();
343      msg << attr;
344      const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
345      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
346        event.push(*itRank,1,msg);
347      contextClientTmp->sendEvent(event);
348    }
349    else contextClientTmp->sendEvent(event);
350  }
351
352
353  /*!
354    This generic funtion only provides instance for sending, for receving, each
355    child class must define itself.
356    \param [in] id Id of added item
357    \param [in] itemType type of added item
358  */
359  template<class T>
360  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType)
361  {
362    CContext* context = CContext::getCurrent();
363    typedef typename T::EEventId ItemType;
364    if (context->hasClient)
365    {
366       // Use correct context client to send message
367//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
368      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
369      for (int i = 0; i < nbSrvPools; ++i)
370      {
371         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
372         CEventClient event(this->getType(),ItemType(itemType));
373         if (contextClientTmp->isServerLeader())
374         {
375           CMessage msg;
376           msg << this->getId();
377           msg << id;
378           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
379           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
380             event.push(*itRank,1,msg);
381           contextClientTmp->sendEvent(event);
382         }
383         else contextClientTmp->sendEvent(event);
384      }
385    }
386  }
387
388  template<class T>
389  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, const int srvPool)
390  {
391    CContext* context = CContext::getCurrent();
392    typedef typename T::EEventId ItemType;
393     CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
394     CEventClient event(this->getType(),ItemType(itemType));
395     if (contextClientTmp->isServerLeader())
396     {
397       CMessage msg;
398       msg << this->getId();
399       msg << id;
400       const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
401       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
402         event.push(*itRank,1,msg);
403       contextClientTmp->sendEvent(event);
404     }
405     else contextClientTmp->sendEvent(event);
406  }
407
408  template <class T>
409  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
410  {
411
412    CBufferIn* buffer=event.subEvents.begin()->buffer;
413    string id,attrId;
414    *buffer>>id;
415    CAttributeMap & attrMap = *get(id);
416    *buffer>>attrId;
417    CAttribute* attr=attrMap[attrId];
418    info(50) << "attribut recu " << attrId << "  ";
419    if (attr->isEmpty()) info(50) << "--> empty" << endl;
420    else info(50) /*<attr->getValue()*/ << endl;
421    *buffer>>*attr;
422     info(50) << "attribut recu " << attrId << "  ";
423    if (attr->isEmpty()) info(50) << "--> empty" << endl;
424    else info(50) /*attr->getValue()*/ << endl;
425  }
426
427   template <class T>
428   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
429   {
430      switch(event.type)
431      {
432         case EVENT_ID_SEND_ATTRIBUTE :
433           recvAttributFromClient(event);
434           return true;
435           break;
436
437         default :
438         return false;
439//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
440      }
441   }
442
443   template <typename T>
444   bool CObjectTemplate<T>::has(const string & id)
445   {
446     return CObjectFactory::HasObject<T>(id);
447   }
448
449   template <typename T>
450   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
451   {
452     return CObjectFactory::HasObject<T>(contextId,id);
453   }
454
455   template <typename T>
456   T* CObjectTemplate<T>::get(const string & id)
457   {
458     return CObjectFactory::GetObject<T>(id).get();
459   }
460
461   template <typename T>
462   T* CObjectTemplate<T>::get(const T* ptr)
463   {
464     return CObjectFactory::GetObject<T>(ptr).get();
465   }
466
467   template <typename T>
468   shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
469   {
470     return CObjectFactory::GetObject<T>(ptr);
471   }
472
473   template <typename T>
474   shared_ptr<T> CObjectTemplate<T>::getShared(void)
475   {
476     return CObjectFactory::GetObject<T>((T*)this);
477   }
478
479   template <typename T>
480   const vector<T*> CObjectTemplate<T>::getAll()
481   {
482     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
483     vector<T*> vect;
484
485     typename vector<shared_ptr<T> >::const_iterator it;
486     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
487     return vect;
488   }
489
490   template <typename T>
491   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
492   {
493     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
494     vector<T*> vect;
495
496     typename vector<shared_ptr<T> >::const_iterator it;
497     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
498     return vect;
499   }
500
501   template <typename T>
502   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
503   {
504     return CObjectFactory::GetObject<T>(contextId,id).get();
505   }
506
507   template <typename T>
508   T* CObjectTemplate<T>::create(const string & id)
509   {
510     return CObjectFactory::CreateObject<T>(id).get();
511   }   ///--------------------------------------------------------------
512
513  template <typename T>
514  T* CObjectTemplate<T>::get(void)
515  {
516    return CObjectFactory::GetObject<T>((T*)this).get();
517  }
518
519   template <typename T>
520   void CObjectTemplate<T>::generateCInterface(ostream& oss)
521   {
522     string className=getName();
523     int found=className.rfind("_group");
524     if (found!=string::npos) className.replace(found,1,0,'x');
525
526     oss << "/* ************************************************************************** *" << iendl;
527     oss << " *               Interface auto generated - do not modify                     *" << iendl;
528     oss << " * ************************************************************************** */" << iendl;
529     oss << iendl;
530     oss << "#include <boost/multi_array.hpp>" << iendl;
531     oss << "#include <boost/shared_ptr.hpp>" << iendl;
532     oss << "#include \"xios.hpp\"" << iendl;
533     oss << "#include \"attribute_template.hpp\"" << iendl;
534     oss << "#include \"object_template.hpp\"" << iendl;
535     oss << "#include \"group_template.hpp\"" << iendl;
536     oss << "#include \"icutil.hpp\"" << iendl;
537     oss << "#include \"icdate.hpp\"" << iendl;
538     oss << "#include \"timer.hpp\"" << iendl;
539     oss << "#include \"node_type.hpp\"" << iendl;
540     oss << iendl;
541     oss << "extern \"C\"" << iendl;
542     oss << "{" << iendl++;
543     oss << "typedef xios::" << getStrType<T>() << "* " << className << "_Ptr;";
544     SuperClassMap::generateCInterface(oss,className);
545     oss << "}" << iendl--;
546   }
547
548   template <typename T>
549   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
550   {
551     string className=getName();
552     int found=className.rfind("_group");
553     if (found!=string::npos) className.replace(found,1,0,'x');
554
555     oss << "! * ************************************************************************** *" << iendl;
556     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
557     oss << "! * ************************************************************************** *" << iendl;
558     oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl;
559     oss << iendl;
560     oss << "MODULE " << className << "_interface_attr" << iendl++;
561     oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl;
562     oss << iendl;
563     oss << "INTERFACE" << iendl++;
564     oss << "! Do not call directly / interface FORTRAN 2003 <-> C99";
565     SuperClassMap::generateFortran2003Interface(oss,className);
566     oss << iendl--;
567     oss << "END INTERFACE" << iendl--;
568     oss << iendl;
569     oss << "END MODULE " << className << "_interface_attr" << iendl;
570   }
571
572   template <typename T>
573   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
574   {
575     string className=getName();
576     int found=className.rfind("_group");
577     if (found!=string::npos) className.erase(found,1);
578     string superClassName=getName();
579     found=superClassName.find("_group");
580     if (found!=string::npos) superClassName.erase(found,6);
581
582     oss << "! * ************************************************************************** *" << iendl;
583     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
584     oss << "! * ************************************************************************** *" << iendl;
585     oss << "#include \"xios_fortran_prefix.hpp\"" << iendl;
586     oss << iendl;
587     oss << "MODULE i" << className << "_attr" << iendl++;
588     oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl;
589     oss << "USE i" << superClassName << iendl;
590     oss << "USE " << className << "_interface_attr" << iendl--;
591//   oss << "TYPE txios(" << className << ")" << iendl;
592//   oss << "  INTEGER(kind = C_INTPTR_T) :: daddr" << iendl;
593//   oss << "END TYPE txios(" << className << ")" << iendl;
594     oss << iendl;
595     oss << "CONTAINS" << iendl;
596     oss << iendl++;
597     SuperClassMap::generateFortranInterface_id(oss,className);
598     oss << iendl;
599     SuperClassMap::generateFortranInterface_hdl(oss,className);
600     oss << iendl;
601     SuperClassMap::generateFortranInterface_hdl_(oss,className);
602     oss << iendl;
603     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
604     oss << iendl;
605     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
606     oss << iendl;
607     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
608     oss << iendl;
609     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
610     oss << iendl;
611     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
612     oss << iendl;
613     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
614     oss << iendl--;
615     oss << "END MODULE i" << className << "_attr" << iendl;
616   }
617} // namespace xios
618
619#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.