Salome HOME
Merge from V6_main 01/04/2013
[modules/yacs.git] / src / engine / DeploymentTree.cxx
1 // Copyright (C) 2006-2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "DeploymentTree.hxx"
21 #include "ComponentInstance.hxx"
22 #include "Container.hxx"
23 #include "Scheduler.hxx"
24 #include "Task.hxx"
25
26 //#define _DEVDEBUG_
27 #include "YacsTrace.hxx"
28
29 using namespace std;
30 using namespace YACS::ENGINE;
31
32 DeploymentTreeOnHeap::DeploymentTreeOnHeap():_cnt(1)
33 {
34 }
35
36 DeploymentTreeOnHeap::~DeploymentTreeOnHeap()
37 {
38 }
39
40 bool DeploymentTreeOnHeap::decrRef()
41 {
42   bool ret=(--_cnt==0);
43   if(ret)
44     delete this;
45   return ret;
46 }
47
48 void DeploymentTreeOnHeap::incrRef() const
49 {
50   _cnt++;
51 }
52
53 unsigned char DeploymentTreeOnHeap::appendTask(Task *task, Scheduler *cloner)
54 {
55   DEBTRACE( "DeploymentTreeOnHeap::appendTask: " << task );
56   if(!task)
57     return DeploymentTree::NULL_TASK;
58   if(!task->isDeployable())//Task not needed to be placed.
59     return DeploymentTree::NOT_DEPLOYABLE_TASK;
60   ComponentInstance *ci=task->getComponent();
61   Container *cont=task->getContainer();
62   DEBTRACE( "DeploymentTreeOnHeap::appendTask component: " << ci );
63   DEBTRACE( "DeploymentTreeOnHeap::appendTask container: " << cont );
64   if(!ci && !cont)//Task is not attached to a Component or a Container -> not needed to be placed.
65     {
66       _freePlacableTasks.push_back(pair<Task *,Scheduler *>(task,cloner));
67       return DeploymentTree::DEPLOYABLE_BUT_NOT_SPECIFIED;
68     }
69   DEBTRACE( "DeploymentTreeOnHeap::appendTask container: " << cont );
70
71   // an iterator for Container level
72   vector< vector< vector< pair<Task *, Scheduler *> > > >::iterator iter1;
73   // an iterator for Component instance level
74   vector< vector< pair<Task *, Scheduler * > > >::iterator iter2;
75   // an iterator for a vector of tasks with same container and component instance
76   vector< pair<Task *, Scheduler *> >::iterator iter3;
77
78   // search an existing vector of tasks with container == cont
79   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
80     {
81       Task* task=(*iter1)[0][0].first;
82       if(task->getContainer() == cont)
83         break;
84     }
85   if(iter1==_tree.end())
86     {
87       // the vector does not exist : create it
88       DEBTRACE("create a vector of vector of tasks for container " << cont);
89       _tree.push_back(vector< vector< pair< Task *, Scheduler *> > >());
90       iter1=_tree.end();
91       iter1--;
92     }
93
94   // search a vector of tasks with component instance == ci
95   for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
96     if(((*iter2)[0]).first->getComponent()==ci)
97       break;
98   if(iter2==(*iter1).end())
99     {
100       // the vector does not exist : create it
101       DEBTRACE("create a vector of tasks for component instance " << ci);
102       (*iter1).push_back(vector< pair< Task *, Scheduler *> >());
103       iter2=(*iter1).end();
104       iter2--;
105     }
106
107   // search the task in the vector. If it exists return 
108   for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
109     if((*iter3).first==task)
110       return DeploymentTree::ALREADY_IN_TREE;
111
112   // if the task is not in the vector add it under condition
113   if(!isConsistentTaskRegardingShCompInst(*iter2,cloner))
114     return DeploymentTree::DUP_TASK_NOT_COMPATIBLE_WITH_EXISTING_TREE;
115   DEBTRACE("add task to vector of tasks " << task);
116   (*iter2).push_back(pair<Task *,Scheduler *>(task,cloner));
117   return DeploymentTree::APPEND_OK;
118 }
119
120 unsigned DeploymentTreeOnHeap::getNumberOfCTDefContainer() const
121 {
122   DEBTRACE("getNumberOfCTDefContainer ");
123   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
124   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
125   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
126   unsigned ret=0;
127   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
128     {
129       bool isCTDefSurely1=true;
130       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++)
131         {
132           bool isCTDefSurely2=true;
133           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++)
134             if((*iter3).second!=0)
135               isCTDefSurely2=false;
136           if(isCTDefSurely2)
137             isCTDefSurely1=true;
138           else if(((*iter2)[0].first)->getComponent())
139             isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
140           else
141             isCTDefSurely1=false;
142         }
143       Container *cont=((*iter1)[0][0].first)->getContainer();
144       if(isCTDefSurely1)
145         {
146           if(cont)
147             ret++;
148         }
149       else
150         if(cont)
151           if(cont->isAttachedOnCloning())
152             ret++;
153           else
154             {
155               unsigned val;
156               if((*iter1)[0][0].second->isMultiplicitySpecified(val))
157                 ret+=val;
158             }
159       }
160   return ret;
161 }
162
163 unsigned DeploymentTreeOnHeap::getNumberOfRTODefContainer() const
164 {
165   DEBTRACE("getNumberOfRTODefContainer");
166   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
167   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
168   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
169   unsigned ret=0;
170   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
171     {
172       bool isRTODefSurely1=true;
173       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++)
174         {
175           bool isRTODefSurely2=true;
176           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++)
177             if((*iter3).second==0)
178               isRTODefSurely2=false;
179           if(isRTODefSurely2)
180             if(((*iter2)[0].first)->getComponent())
181               isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
182             else
183               isRTODefSurely1=false;
184           else
185             isRTODefSurely1=false;
186         }
187       if(isRTODefSurely1)
188         if(((*iter1)[0][0].first)->getContainer())
189           if(!((*iter1)[0][0].first)->getContainer()->isAttachedOnCloning())
190             ret++;
191     }
192   return ret;
193 }
194
195 unsigned DeploymentTreeOnHeap::getNumberOfCTDefComponentInstances() const
196 {
197   DEBTRACE("getNumberOfCTDefComponentInstances");
198   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
199   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
200   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
201   unsigned ret=0;
202   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
203     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
204       {
205         bool isCTDefSurely=true;
206         for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely;iter3++)
207           if((*iter3).second!=0)
208             isCTDefSurely=false;
209         if(isCTDefSurely)
210           ret++;
211         else
212           if(((*iter2)[0].first)->getComponent() && ((*iter2)[0].first)->getComponent()->isAttachedOnCloning())
213             ret++;
214       }
215   return ret;
216 }
217
218 unsigned DeploymentTreeOnHeap::getNumberOfRTODefComponentInstances() const
219 {
220   DEBTRACE("getNumberOfRTODefComponentInstances");
221   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
222   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
223   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
224   unsigned ret=0;
225   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
226     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
227       {
228         bool isRTODef=false;
229         for(iter3=(*iter2).begin();iter3!=(*iter2).end() && !isRTODef;iter3++)
230           if((*iter3).second!=0)
231             isRTODef=true;
232         if(isRTODef && ((*iter2)[0].first)->getComponent() && !((*iter2)[0].first)->getComponent()->isAttachedOnCloning())
233           ret++;
234       }
235   return ret;
236 }
237
238 std::vector<Container *> DeploymentTreeOnHeap::getAllContainers() const
239 {
240   vector<Container *> ret;
241   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
242   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
243     {
244       Task* task=(*iter1)[0][0].first;
245       ret.push_back(task->getContainer());
246     }
247   return ret;
248 }
249
250 std::vector<Container *> DeploymentTreeOnHeap::getAllCTDefContainers() const
251 {
252   DEBTRACE("getAllCTDefContainers");
253   vector<Container *> ret;
254   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
255   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
256   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
257   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
258     {
259       bool isCTDefSurely1=true;
260       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++)
261         {
262           bool isCTDefSurely2=true;
263           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++)
264             if((*iter3).second!=0)
265               isCTDefSurely2=false;
266           if(isCTDefSurely2)
267             isCTDefSurely1=true;
268           else if(((*iter2)[0].first)->getComponent())
269             isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
270           else
271             isCTDefSurely1=false;
272         }
273       Container *cont=((*iter1)[0][0].first)->getContainer();
274       if(isCTDefSurely1)
275         {
276           if(cont)
277             ret.push_back(cont);
278         }
279       else
280         if(cont)
281           if(cont->isAttachedOnCloning())
282             ret.push_back(cont);
283       }
284   return ret;
285 }
286
287 std::vector<Container *> DeploymentTreeOnHeap::getAllRTODefContainers() const
288 {
289   DEBTRACE("getAllRTODefContainers");
290   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
291   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
292   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
293   vector<Container *> ret;
294   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
295     {
296       bool isRTODefSurely1=true;
297       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++)
298         {
299           bool isRTODefSurely2=true;
300           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++)
301             if((*iter3).second==0)
302               isRTODefSurely2=false;
303           if(isRTODefSurely2)
304             {
305               if(((*iter2)[0].first)->getComponent())
306                 isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
307               else
308                 isRTODefSurely1=false;
309             }
310           else
311             isRTODefSurely1=false;
312         }
313       if(isRTODefSurely1)
314         {
315           Container* cont= (*iter1)[0][0].first->getContainer();
316           if(cont)
317             if(!cont->isAttachedOnCloning())
318               ret.push_back(cont);
319         }
320     }
321   return ret;
322 }
323
324 std::vector<Task *> DeploymentTreeOnHeap::getTasksLinkedToContainer(Container *cont) const
325 {
326   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
327   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
328   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
329   
330   std::vector<Task *> ret;
331   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
332     {
333       if(((*iter1)[0][0].first)->getContainer()==cont)
334         for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
335           if(((*iter2)[0].first)->getComponent()==0)
336             for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
337               ret.push_back((*iter3).first);
338     }
339   return ret;
340 }
341
342 std::vector<Task *> DeploymentTreeOnHeap::getTasksLinkedToComponent(ComponentInstance *comp) const
343 {
344   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
345   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
346   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
347   
348   std::vector<Task *> ret;
349   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
350     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
351       if(((*iter2)[0].first)->getComponent()==comp)
352         for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
353           ret.push_back((*iter3).first);
354   return ret;
355 }
356
357 std::vector<ComponentInstance *> DeploymentTreeOnHeap::getComponentsLinkedToContainer(Container *cont) const
358 {
359   DEBTRACE("DeploymentTreeOnHeap::getComponentsLinkedToContainer ");
360   vector<ComponentInstance *> ret;
361   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
362   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
363   //iterate on containers
364   for(iter1=_tree.begin();iter1!=_tree.end();++iter1)
365     {
366       //iterate on components
367       for(iter2=(*iter1).begin();iter2!=(*iter1).end();++iter2)
368         {
369           ComponentInstance *compo=(*iter2)[0].first->getComponent();
370           if(compo)
371             {
372               //it's a real component, add it if its container is the right one
373               if(compo->getContainer()==cont)
374                 ret.push_back(compo);
375               else
376                 break;
377             }
378         }
379     }
380     
381   return ret;
382 }
383
384 bool DeploymentTreeOnHeap::presenceOfDefaultContainer() const
385 {
386   DEBTRACE("presenceOfDefaultContainer");
387   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
388   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
389     if(!((*iter1)[0][0].first)->getContainer())
390       return true;
391   return false;
392 }
393
394 std::vector<Task *> DeploymentTreeOnHeap::getFreeDeployableTasks() const
395 {
396   vector<Task *> ret;
397   for(vector< pair<Task *,Scheduler *> >::const_iterator iter=_freePlacableTasks.begin();iter!=_freePlacableTasks.end();iter++)
398     ret.push_back((*iter).first);
399   return ret;
400 }
401
402 bool DeploymentTreeOnHeap::isConsistentTaskRegardingShCompInst(std::vector< std::pair<Task *, Scheduler * > >& tasksSharingSameCompInst, Scheduler *cloner)
403 {
404   vector< std::pair<Task *, Scheduler * > >::const_iterator iter;
405   bool coexistenceOfDifferentSched=false;
406   for(iter=tasksSharingSameCompInst.begin();iter!=tasksSharingSameCompInst.end() && !coexistenceOfDifferentSched;iter++)
407     {
408       coexistenceOfDifferentSched=(((*iter).second)!=cloner);
409     }
410   if(!coexistenceOfDifferentSched)
411     return true;
412   //In this case the component is duplicated on cloning raising on runtime on different policy (schedulers) than other tasks in tasksSharingSameCompInst
413   if((tasksSharingSameCompInst[0].first)->getComponent())
414     return (tasksSharingSameCompInst[0].first)->getComponent()->isAttachedOnCloning();
415   else
416     return (tasksSharingSameCompInst[0].first)->getContainer()->isAttachedOnCloning();
417 }
418
419 DeploymentTree::DeploymentTree():_treeHandle(0)
420 {
421 }
422
423 DeploymentTree::~DeploymentTree()
424 {
425   if(_treeHandle)
426     _treeHandle->decrRef();
427 }
428
429 DeploymentTree::DeploymentTree(const DeploymentTree& other)
430 {
431   _treeHandle=other._treeHandle;
432   if(_treeHandle)
433     _treeHandle->incrRef();
434 }
435
436 const DeploymentTree &DeploymentTree::operator=(const DeploymentTree& other)
437 {
438   if(_treeHandle)
439     _treeHandle->decrRef();
440   _treeHandle=other._treeHandle;
441   if(_treeHandle)
442     _treeHandle->incrRef();
443   return *this;
444 }
445
446 unsigned char DeploymentTree::appendTask(Task *task, Scheduler *cloner)
447 {
448   if(_treeHandle)
449     return _treeHandle->appendTask(task,cloner);
450   if(!task)
451     return DeploymentTree::NULL_TASK;
452   if(!task->isDeployable())//Task not needed to be placed.
453     return DeploymentTree::NOT_DEPLOYABLE_TASK;
454   _treeHandle=new DeploymentTreeOnHeap;
455   return _treeHandle->appendTask(task,cloner);
456 }
457
458 /*!
459  * Returns number of containers predictably launchable \b without counting default container.
460  */
461 unsigned DeploymentTree::getNumberOfCTDefContainer() const
462 {
463   if(_treeHandle)
464     return _treeHandle->getNumberOfCTDefContainer();
465   return 0;
466 }
467
468 /*!
469  * Returns number of containers unpredictably launchable \b without counting default container.
470  */
471 unsigned DeploymentTree::getNumberOfRTODefContainer() const
472 {
473   if(_treeHandle)
474     return _treeHandle->getNumberOfRTODefContainer();
475   return 0;
476 }
477
478 unsigned DeploymentTree::getNumberOfCTDefComponentInstances() const
479 {
480   if(_treeHandle)
481     return _treeHandle->getNumberOfCTDefComponentInstances();
482   return 0;
483 }
484
485 unsigned DeploymentTree::getNumberOfRTODefComponentInstances() const
486 {
487   if(_treeHandle)
488     return _treeHandle->getNumberOfRTODefComponentInstances();
489   return 0;
490 }
491
492 /*!
493  * Returns all containers default included (0).
494  */
495 std::vector<Container *> DeploymentTree::getAllContainers() const
496 {
497   if(_treeHandle)
498     return _treeHandle->getAllContainers();
499   return vector<Container *>();
500 }
501
502 /*!
503  * Returns containers predictably launchable \b without counting default container.
504  */
505 std::vector<Container *> DeploymentTree::getAllCTDefContainers() const
506 {
507   if(_treeHandle)
508     return _treeHandle->getAllCTDefContainers();
509   return vector<Container *>();
510 }
511
512 /*!
513  * Returns containers unpredictably launchable \b without counting default container.
514  */
515 std::vector<Container *> DeploymentTree::getAllRTODefContainers() const
516 {
517   if(_treeHandle)
518     return _treeHandle->getAllRTODefContainers();
519   return vector<Container *>();
520 }
521
522 std::vector<Task *> DeploymentTree::getTasksLinkedToContainer(Container *cont) const
523 {
524   if(_treeHandle)
525     return _treeHandle->getTasksLinkedToContainer(cont);
526   return vector<Task *>();
527 }
528
529 std::vector<Task *> DeploymentTree::getTasksLinkedToComponent(ComponentInstance *comp) const
530 {
531   if(_treeHandle)
532     return _treeHandle->getTasksLinkedToComponent(comp);
533   return vector<Task *>();
534 }
535
536 std::vector<ComponentInstance *> DeploymentTree::getComponentsLinkedToContainer(Container *cont) const
537 {
538   if(_treeHandle)
539     return _treeHandle->getComponentsLinkedToContainer(cont);
540   return vector<ComponentInstance *>();
541 }
542
543 bool DeploymentTree::presenceOfDefaultContainer() const
544 {
545   if(_treeHandle)
546     return _treeHandle->presenceOfDefaultContainer();
547   return false;
548 }
549
550 bool DeploymentTree::isNull() const
551 {
552   return _treeHandle==0;
553 }
554
555 std::vector<Task *> DeploymentTree::getFreeDeployableTasks() const
556 {
557   if(_treeHandle)
558     return _treeHandle->getFreeDeployableTasks();
559   return vector<Task *>();
560 }