Version: 8.3.0
Bloc.hxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 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 #ifndef __BLOC_HXX__
21 #define __BLOC_HXX__
22 
23 #include "YACSlibEngineExport.hxx"
25 
26 namespace YACS
27 {
28  namespace ENGINE
29  {
31  {
32  protected:
33  std::list<Node *> _setOfNode;//OWNERSHIP OF ALL NODES
35  mutable std::map<Node *,std::set<Node *> > *_fwLinks;
37  mutable std::map<Node *,std::set<Node *> > *_bwLinks;
38  protected:
39  Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
40  public:
41  Bloc(const Bloc& other, ComposedNode *father, bool editionOnly);
42  Bloc(const std::string& name);
43  virtual ~Bloc();
44  bool isFinished();
45  int getNumberOfCFLinks() const;
46  void init(bool start=true);
47  void getReadyTasks(std::vector<Task *>& tasks);
48  void exUpdateState();
49  //Node* DISOWNnode is a SWIG notation to indicate that the ownership of the node is transfered to C++
50  bool edAddChild(Node *DISOWNnode) throw(Exception);
51  void edRemoveChild(Node *node) throw(Exception);
52  std::list<Node *> getChildren() const { return _setOfNode; }
53  std::list<Node *> edGetDirectDescendants() const { return _setOfNode; }
54  std::vector< std::list<Node *> > splitIntoIndependantGraph() const;
55  Node *getChildByShortName(const std::string& name) const throw(Exception);
56  virtual void writeDot(std::ostream &os) const;
57  void accept(Visitor *visitor);
58  template<bool direction>
59  void findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec, std::map<Node *, std::set<Node *> >& accelStr) const;
60  template<bool direction>
61  void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
62  virtual std::string typeName() { return "YACS__ENGINE__Bloc"; }
63  int getMaxLevelOfParallelism() const;
64  void removeRecursivelyRedundantCL();
65  protected:
66  bool areAllSubNodesFinished() const;
67  bool areAllSubNodesDone() const;
68  bool isNameAlreadyUsed(const std::string& name) const;
69  void checkNoCyclePassingThrough(Node *node) throw(Exception);
70  std::vector< std::pair<OutGate *, InGate *> > getSetOfInternalCFLinks() const;
71  YACS::Event updateStateOnFinishedEventFrom(Node *node);
72  YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
73  void initComputation() const;
74  void performCFComputationsOnlyOneLevel(LinkInfo& info) const;
75  void performCFComputations(LinkInfo& info) const;
76  void destructCFComputations(LinkInfo& info) const;
77  void checkControlDependancy(OutPort *start, InPort *end, bool cross,
78  std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
79  std::vector<OutPort *>& fwCross,
80  std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
81  LinkInfo& info) const;
82  bool areLinked(Node *start, Node *end, bool fw) const;
83  bool arePossiblyRunnableAtSameTime(Node *start, Node *end) const;
84  void checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const;
85  static void verdictForOkAndUseless1(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::vector<Node *>& candidates,
86  unsigned char& alreadyFed, bool direction, LinkInfo& info);
87  static void verdictForCollapses(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::set<Node *>& candidates,
88  unsigned char& alreadyFed, bool direction, LinkInfo& info);
89  void seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const;
90  void seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const;
91  private:
92  static void findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info);
93  template<bool direction>
94  static unsigned appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder);
95  static void updateWithNewFind(const std::vector<Node *>& path, std::map<Node *, std::set<Node *> >& fastFinder);
96  };
97 
98  template<bool direction>
100  {
101  };
102 
103  template<>
104  struct CFDirectionVisTraits<true>
105  {
106  typedef std::list< std::pair<InGate *,bool> >::iterator Iterator;
107  typedef std::list< std::pair<InGate *,bool> >& Nexts;
108  static Nexts getNexts(Node *node) { return node->getOutGate()->edMapInGate(); }
109  };
110 
111 
112  template<>
113  struct CFDirectionVisTraits<false>
114  {
115  typedef std::list< std::pair<OutGate *,bool> >::iterator Iterator;
116  typedef std::list< std::pair<OutGate *,bool> >& Nexts;
117  static Nexts getNexts(Node *node) { return node->getInGate()->edMapOutGate(); }
118  };
119 
124  template<bool direction>
125  unsigned Bloc::appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder)
126  {
127  std::map<Node *, std::set<Node *> >::iterator iter=fastFinder.find(node);
128  if(iter==fastFinder.end())
129  return 0;
130  unsigned ret=0;
131  std::vector<std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator > > li;
132  std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator> ipr(((*iter).second).begin(),((*iter).second).end());
133  li.push_back(ipr);
134  std::vector<Node *> work(startRes);
135  std::list< std::vector<Node *> >::iterator where=res.end(); where--;
136  std::list< std::vector<Node *> >::iterator updates=where;
137  while(!li.empty())
138  {
139  if(li.back().first!=li.back().second)
140  {
141  work.push_back(*(li.back().first));
142  if(CFDirectionVisTraits<direction>::getNexts(work.back()).empty())
143  {
144  where=res.insert(where,work);
145  ret++;
146  li.back().first++;
147  work.pop_back();
148  }
149  else
150  {
151  std::set<Node *>& s=fastFinder[*(li.back().first)];
152  std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator> pr(s.begin(),s.end());
153  li.push_back(pr);
154  }
155  }
156  else
157  {
158  work.pop_back();
159  li.pop_back();
160  if(!li.empty())
161  li.back().first++;
162  }
163  }
164  updates--;
165  for(unsigned i=0;i<ret;i++,updates--)
166  updateWithNewFind(*updates,fastFinder);
167  return ret;
168  }
169 
170  template<bool direction>
171  void Bloc::findAllNodesStartingFrom(Node *start, std::set<Node *>& result,
172  std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const
173  {
174  std::list< std::vector<Node *> > li;
175  findAllPathsStartingFrom<direction>(start,li,accelStr);
176  for(std::list< std::vector<Node *> >::const_iterator iter=li.begin();iter!=li.end();iter++)
177  for(std::vector<Node *>::const_iterator iter2=(*iter).begin()+1;iter2!=(*iter).end();iter2++)
178  result.insert(*iter2);
179  if(direction)
180  findUselessLinksIn(li,info);
181  }
182 
190  template<bool direction>
191  void Bloc::findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec,
192  std::map<Node *, std::set<Node *> >& accelStr) const
193  {
194  initComputation();
195  Node *current=start;
196  int caseId=0;
197  int idInCase=0;
198  vec.push_back(std::vector<Node *>());
200  std::list< std::vector<Node *> >::iterator curLine=vec.begin();
201  while(start->_colour!=YACS::Black)
202  {
203  (*curLine).push_back(current);
204  idInCase++;
205  //
206  if(CFDirectionVisTraits<direction>::getNexts(current).empty())
207  {
208 
209  vec.push_back(std::vector<Node *>((*curLine)));
210  updateWithNewFind(*curLine,accelStr);
211  current->_colour=YACS::Black;
212  curLine++;
213  if(idInCase>1)
214  {
215  idInCase-=2;
216  current=(*curLine)[idInCase];
217  (*curLine).pop_back();
218  (*curLine).pop_back();
219  }
220  continue;
221  }
222  if(current->_colour==YACS::Black)
223  {
224  appendIfAlreadyFound<direction>(vec,(*curLine),current,accelStr);
225  curLine=vec.end(); curLine--;
226  current->_colour=YACS::Black;
227  if(idInCase>1)
228  {
229  idInCase-=2;
230  current=(*curLine)[idInCase];
231  (*curLine).pop_back();
232  (*curLine).pop_back();
233  }
234  continue;
235  }
236  for(iter=CFDirectionVisTraits<direction>::getNexts(current).begin();iter!=CFDirectionVisTraits<direction>::getNexts(current).end();iter++)
237  if(!(*iter).second)
238  break;
239  if(iter==CFDirectionVisTraits<direction>::getNexts(current).end())
240  {//Fail this branch should be forgotten go rev
241  current->_colour=YACS::Black;
242  (*curLine).pop_back();
243  if(idInCase>1)
244  {
245  idInCase-=2;
246  current=(*curLine)[idInCase];
247  (*curLine).pop_back();
248  }
249  }
250  else
251  {
252  //Nothing to signal continuing in this direction hoping to find
253  current=(*iter).first->getNode();
254  (*iter).second=true;
255  }
256  }
257  vec.pop_back();
258  }
259  }
260 }
261 
262 
263 #endif