Salome HOME
Copyright update 2020
[modules/yacs.git] / src / engine / DeploymentTree.cxx
1 // Copyright (C) 2006-2020  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, or (at your option) any later version.
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   DEBTRACE("add task to vector of tasks " << task);
113   (*iter2).push_back(pair<Task *,Scheduler *>(task,cloner));
114   return DeploymentTree::APPEND_OK;
115 }
116
117 unsigned DeploymentTreeOnHeap::getNumberOfCTDefContainer() const
118 {
119   DEBTRACE("getNumberOfCTDefContainer ");
120   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
121   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
122   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
123   unsigned ret=0;
124   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
125     {
126       bool isCTDefSurely1=true;
127       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++)
128         {
129           bool isCTDefSurely2=true;
130           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++)
131             if((*iter3).second!=0)
132               isCTDefSurely2=false;
133           if(isCTDefSurely2)
134             isCTDefSurely1=true;
135           else if(((*iter2)[0].first)->getComponent())
136             isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
137           else
138             isCTDefSurely1=false;
139         }
140       Container *cont=((*iter1)[0][0].first)->getContainer();
141       if(isCTDefSurely1)
142         {
143           if(cont)
144             ret++;
145         }
146       else
147         if(cont)
148           if(cont->isAttachedOnCloning())
149             ret++;
150           else
151             {
152               unsigned val;
153               if((*iter1)[0][0].second->isMultiplicitySpecified(val))
154                 ret+=val;
155             }
156       }
157   return ret;
158 }
159
160 unsigned DeploymentTreeOnHeap::getNumberOfRTODefContainer() const
161 {
162   DEBTRACE("getNumberOfRTODefContainer");
163   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
164   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
165   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
166   unsigned ret=0;
167   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
168     {
169       bool isRTODefSurely1=true;
170       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++)
171         {
172           bool isRTODefSurely2=true;
173           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++)
174             if((*iter3).second==0)
175               isRTODefSurely2=false;
176           if(isRTODefSurely2)
177             if(((*iter2)[0].first)->getComponent())
178               isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
179             else
180               isRTODefSurely1=false;
181           else
182             isRTODefSurely1=false;
183         }
184       if(isRTODefSurely1)
185         if(((*iter1)[0][0].first)->getContainer())
186           if(!((*iter1)[0][0].first)->getContainer()->isAttachedOnCloning())
187             ret++;
188     }
189   return ret;
190 }
191
192 unsigned DeploymentTreeOnHeap::getNumberOfCTDefComponentInstances() const
193 {
194   DEBTRACE("getNumberOfCTDefComponentInstances");
195   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
196   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
197   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
198   unsigned ret=0;
199   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
200     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
201       {
202         bool isCTDefSurely=true;
203         for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely;iter3++)
204           if((*iter3).second!=0)
205             isCTDefSurely=false;
206         if(isCTDefSurely)
207           ret++;
208         else
209           if(((*iter2)[0].first)->getComponent() && ((*iter2)[0].first)->getComponent()->isAttachedOnCloning())
210             ret++;
211       }
212   return ret;
213 }
214
215 unsigned DeploymentTreeOnHeap::getNumberOfRTODefComponentInstances() const
216 {
217   DEBTRACE("getNumberOfRTODefComponentInstances");
218   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
219   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
220   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
221   unsigned ret=0;
222   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
223     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
224       {
225         bool isRTODef=false;
226         for(iter3=(*iter2).begin();iter3!=(*iter2).end() && !isRTODef;iter3++)
227           if((*iter3).second!=0)
228             isRTODef=true;
229         if(isRTODef && ((*iter2)[0].first)->getComponent() && !((*iter2)[0].first)->getComponent()->isAttachedOnCloning())
230           ret++;
231       }
232   return ret;
233 }
234
235 std::vector<Container *> DeploymentTreeOnHeap::getAllContainers() const
236 {
237   vector<Container *> ret;
238   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
239   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
240     {
241       Task* task=(*iter1)[0][0].first;
242       ret.push_back(task->getContainer());
243     }
244   return ret;
245 }
246
247 std::vector<Container *> DeploymentTreeOnHeap::getAllCTDefContainers() const
248 {
249   DEBTRACE("getAllCTDefContainers");
250   vector<Container *> ret;
251   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
252   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
253   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
254   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
255     {
256       bool isCTDefSurely1=true;
257       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isCTDefSurely1;iter2++)
258         {
259           bool isCTDefSurely2=true;
260           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isCTDefSurely2;iter3++)
261             if((*iter3).second!=0)
262               isCTDefSurely2=false;
263           if(isCTDefSurely2)
264             isCTDefSurely1=true;
265           else if(((*iter2)[0].first)->getComponent())
266             isCTDefSurely1=(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
267           else
268             isCTDefSurely1=false;
269         }
270       Container *cont=((*iter1)[0][0].first)->getContainer();
271       if(isCTDefSurely1)
272         {
273           if(cont)
274             ret.push_back(cont);
275         }
276       else
277         if(cont)
278           if(cont->isAttachedOnCloning())
279             ret.push_back(cont);
280       }
281   return ret;
282 }
283
284 std::vector<Container *> DeploymentTreeOnHeap::getAllRTODefContainers() const
285 {
286   DEBTRACE("getAllRTODefContainers");
287   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
288   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
289   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
290   vector<Container *> ret;
291   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
292     {
293       bool isRTODefSurely1=true;
294       for(iter2=(*iter1).begin();iter2!=(*iter1).end() && isRTODefSurely1;iter2++)
295         {
296           bool isRTODefSurely2=true;
297           for(iter3=(*iter2).begin();iter3!=(*iter2).end() && isRTODefSurely2;iter3++)
298             if((*iter3).second==0)
299               isRTODefSurely2=false;
300           if(isRTODefSurely2)
301             {
302               if(((*iter2)[0].first)->getComponent())
303                 isRTODefSurely1=!(((*iter2)[0].first)->getComponent()->isAttachedOnCloning());
304               else
305                 isRTODefSurely1=false;
306             }
307           else
308             isRTODefSurely1=false;
309         }
310       if(isRTODefSurely1)
311         {
312           Container* cont= (*iter1)[0][0].first->getContainer();
313           if(cont)
314             if(!cont->isAttachedOnCloning())
315               ret.push_back(cont);
316         }
317     }
318   return ret;
319 }
320
321 std::vector<Task *> DeploymentTreeOnHeap::getTasksLinkedToContainer(Container *cont) const
322 {
323   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
324   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
325   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
326   
327   std::vector<Task *> ret;
328   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
329     {
330       if(((*iter1)[0][0].first)->getContainer()==cont)
331         for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
332           if(((*iter2)[0].first)->getComponent()==0)
333             for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
334               ret.push_back((*iter3).first);
335     }
336   return ret;
337 }
338
339 std::vector<Task *> DeploymentTreeOnHeap::getTasksLinkedToComponent(ComponentInstance *comp) const
340 {
341   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
342   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
343   vector< pair<Task *, Scheduler *> >::const_iterator iter3;
344   
345   std::vector<Task *> ret;
346   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
347     for(iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++)
348       if(((*iter2)[0].first)->getComponent()==comp)
349         for(iter3=(*iter2).begin();iter3!=(*iter2).end();iter3++)
350           ret.push_back((*iter3).first);
351   return ret;
352 }
353
354 std::vector<ComponentInstance *> DeploymentTreeOnHeap::getComponentsLinkedToContainer(Container *cont) const
355 {
356   DEBTRACE("DeploymentTreeOnHeap::getComponentsLinkedToContainer ");
357   vector<ComponentInstance *> ret;
358   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
359   vector< vector< pair<Task *, Scheduler * > > >::const_iterator iter2;
360   //iterate on containers
361   for(iter1=_tree.begin();iter1!=_tree.end();++iter1)
362     {
363       //iterate on components
364       for(iter2=(*iter1).begin();iter2!=(*iter1).end();++iter2)
365         {
366           ComponentInstance *compo=(*iter2)[0].first->getComponent();
367           if(compo)
368             {
369               //it's a real component, add it if its container is the right one
370               if(compo->getContainer()==cont)
371                 ret.push_back(compo);
372               else
373                 break;
374             }
375         }
376     }
377     
378   return ret;
379 }
380
381 bool DeploymentTreeOnHeap::presenceOfDefaultContainer() const
382 {
383   DEBTRACE("presenceOfDefaultContainer");
384   vector< vector< vector< pair<Task *, Scheduler *> > > >::const_iterator iter1;
385   for(iter1=_tree.begin();iter1!=_tree.end();iter1++)
386     if(!((*iter1)[0][0].first)->getContainer())
387       return true;
388   return false;
389 }
390
391 std::vector<Task *> DeploymentTreeOnHeap::getFreeDeployableTasks() const
392 {
393   vector<Task *> ret;
394   for(vector< pair<Task *,Scheduler *> >::const_iterator iter=_freePlacableTasks.begin();iter!=_freePlacableTasks.end();iter++)
395     ret.push_back((*iter).first);
396   return ret;
397 }
398
399 DeploymentTree::DeploymentTree():_treeHandle(0)
400 {
401 }
402
403 DeploymentTree::~DeploymentTree()
404 {
405   if(_treeHandle)
406     _treeHandle->decrRef();
407 }
408
409 DeploymentTree::DeploymentTree(const DeploymentTree& other)
410 {
411   _treeHandle=other._treeHandle;
412   if(_treeHandle)
413     _treeHandle->incrRef();
414 }
415
416 const DeploymentTree &DeploymentTree::operator=(const DeploymentTree& other)
417 {
418   if(_treeHandle)
419     _treeHandle->decrRef();
420   _treeHandle=other._treeHandle;
421   if(_treeHandle)
422     _treeHandle->incrRef();
423   return *this;
424 }
425
426 unsigned char DeploymentTree::appendTask(Task *task, Scheduler *cloner)
427 {
428   if(_treeHandle)
429     return _treeHandle->appendTask(task,cloner);
430   if(!task)
431     return DeploymentTree::NULL_TASK;
432   if(!task->isDeployable())//Task not needed to be placed.
433     return DeploymentTree::NOT_DEPLOYABLE_TASK;
434   _treeHandle=new DeploymentTreeOnHeap;
435   return _treeHandle->appendTask(task,cloner);
436 }
437
438 /*!
439  * Returns number of containers predictably launchable \b without counting default container.
440  */
441 unsigned DeploymentTree::getNumberOfCTDefContainer() const
442 {
443   if(_treeHandle)
444     return _treeHandle->getNumberOfCTDefContainer();
445   return 0;
446 }
447
448 /*!
449  * Returns number of containers unpredictably launchable \b without counting default container.
450  */
451 unsigned DeploymentTree::getNumberOfRTODefContainer() const
452 {
453   if(_treeHandle)
454     return _treeHandle->getNumberOfRTODefContainer();
455   return 0;
456 }
457
458 unsigned DeploymentTree::getNumberOfCTDefComponentInstances() const
459 {
460   if(_treeHandle)
461     return _treeHandle->getNumberOfCTDefComponentInstances();
462   return 0;
463 }
464
465 unsigned DeploymentTree::getNumberOfRTODefComponentInstances() const
466 {
467   if(_treeHandle)
468     return _treeHandle->getNumberOfRTODefComponentInstances();
469   return 0;
470 }
471
472 /*!
473  * Returns all containers default included (0).
474  */
475 std::vector<Container *> DeploymentTree::getAllContainers() const
476 {
477   if(_treeHandle)
478     return _treeHandle->getAllContainers();
479   return vector<Container *>();
480 }
481
482 /*!
483  * Returns containers predictably launchable \b without counting default container.
484  */
485 std::vector<Container *> DeploymentTree::getAllCTDefContainers() const
486 {
487   if(_treeHandle)
488     return _treeHandle->getAllCTDefContainers();
489   return vector<Container *>();
490 }
491
492 /*!
493  * Returns containers unpredictably launchable \b without counting default container.
494  */
495 std::vector<Container *> DeploymentTree::getAllRTODefContainers() const
496 {
497   if(_treeHandle)
498     return _treeHandle->getAllRTODefContainers();
499   return vector<Container *>();
500 }
501
502 std::vector<Task *> DeploymentTree::getTasksLinkedToContainer(Container *cont) const
503 {
504   if(_treeHandle)
505     return _treeHandle->getTasksLinkedToContainer(cont);
506   return vector<Task *>();
507 }
508
509 std::vector<Task *> DeploymentTree::getTasksLinkedToComponent(ComponentInstance *comp) const
510 {
511   if(_treeHandle)
512     return _treeHandle->getTasksLinkedToComponent(comp);
513   return vector<Task *>();
514 }
515
516 std::vector<ComponentInstance *> DeploymentTree::getComponentsLinkedToContainer(Container *cont) const
517 {
518   if(_treeHandle)
519     return _treeHandle->getComponentsLinkedToContainer(cont);
520   return vector<ComponentInstance *>();
521 }
522
523 bool DeploymentTree::presenceOfDefaultContainer() const
524 {
525   if(_treeHandle)
526     return _treeHandle->presenceOfDefaultContainer();
527   return false;
528 }
529
530 bool DeploymentTree::isNull() const
531 {
532   return _treeHandle==0;
533 }
534
535 std::vector<Task *> DeploymentTree::getFreeDeployableTasks() const
536 {
537   if(_treeHandle)
538     return _treeHandle->getFreeDeployableTasks();
539   return vector<Task *>();
540 }