Version: 8.3.0
Bloc.cxx
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 #include "Bloc.hxx"
21 #include "LinkInfo.hxx"
22 #include "InputPort.hxx"
23 #include "InputDataStreamPort.hxx"
24 #include "OutputPort.hxx"
25 #include "OutputDataStreamPort.hxx"
26 #include "ElementaryNode.hxx"
27 #include "Visitor.hxx"
28 #include "SetOfPoints.hxx"
29 
30 #include <queue>
31 #include <iostream>
32 #include <numeric>
33 
34 //#define _DEVDEBUG_
35 #include "YacsTrace.hxx"
36 
37 using namespace YACS::ENGINE;
38 using namespace std;
39 
46 Bloc::Bloc(const Bloc& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_fwLinks(0),_bwLinks(0)
47 {
48  for(list<Node *>::const_iterator iter=other._setOfNode.begin();iter!=other._setOfNode.end();iter++)
49  _setOfNode.push_back((*iter)->simpleClone(this,editionOnly));
50 
51  //CF Linking
52  vector< pair<OutGate *, InGate *> > cfLinksToReproduce=other.getSetOfInternalCFLinks();
53  vector< pair<OutGate *, InGate *> >::iterator iter1=cfLinksToReproduce.begin();
54  for(;iter1!=cfLinksToReproduce.end();iter1++)
55  edAddCFLink(getChildByName(other.getChildName((*iter1).first->getNode())),getChildByName(other.getChildName((*iter1).second->getNode())));
56 
57  //Data + DataStream linking
58  vector< pair<OutPort *, InPort *> > linksToReproduce=other.getSetOfInternalLinks();
59  vector< pair<OutPort *, InPort *> >::iterator iter2=linksToReproduce.begin();
60  for(;iter2!=linksToReproduce.end();iter2++)
61  {
62  OutPort* pout = iter2->first;
63  InPort* pin = iter2->second;
64  if(&other == getLowestCommonAncestor(pout->getNode(), pin->getNode()))
65  {
66  edAddLink(getOutPort(other.getPortName(pout)),getInPort(other.getPortName(pin)));
67  }
68  }
69 }
70 
72 
75 Bloc::Bloc(const std::string& name):StaticDefinedComposedNode(name),_fwLinks(0),_bwLinks(0)
76 {
77 }
78 
80 {
81  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
82  delete *iter;
83  delete _fwLinks;
84  delete _bwLinks;
85 }
86 
88 
93 void Bloc::init(bool start)
94 {
95  Node::init(start);
96  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
97  (*iter)->init(start);
98 }
99 
101 
106 {
107  if(_state==YACS::DONE)return true;
108  if(_state==YACS::ERROR)return true;
109  if(_state==YACS::FAILED)return true;
110  if(_state==YACS::DISABLED)return true;
111  return false;
112 }
113 
115 {
116  int ret=0;
117  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
118  ret+=(*iter)->getOutGate()->getNbOfInGatesConnected();
119  return ret;
120 }
121 
122 Node *Bloc::simpleClone(ComposedNode *father, bool editionOnly) const
123 {
124  return new Bloc(*this,father,editionOnly);
125 }
126 
128 
131 void Bloc::getReadyTasks(std::vector<Task *>& tasks)
132 {
133  /*
134  * ComposedNode state goes to ACTIVATED when one of its child has been ACTIVATED
135  * To change this uncomment the following line
136  * Then the father node will go to ACTIVATED state before its child node
137  */
140  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
141  (*iter)->getReadyTasks(tasks);
142 }
143 
145 
152 {
153  if(_state == YACS::DISABLED)return;
154  if(_state == YACS::DONE)return;
155  if(_inGate.exIsReady())
156  {
158  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
159  if((*iter)->exIsControlReady())
160  (*iter)->exUpdateState();
161  }
162 }
163 
165 
175 {
176  if(isNodeAlreadyAggregated(node))
177  {
178  if(node->_father==this)
179  return false;
180  else
181  {
182  string what = "Bloc::edAddChild : node "; what += node->getName();
183  what += " is already grand children of node";
184  throw Exception(what);
185  }
186  }
187 
188  if(node->_father)
189  {
190  string what = "Bloc::edAddChild: node is not orphan: "; what += node->getName();
191  throw Exception(what);
192  }
193 
194  checkNoCrossHierachyWith(node);
195 
196  if(isNameAlreadyUsed(node->getName()))
197  {
198  string what("Bloc::edAddChild : name "); what+=node->getName();
199  what+=" already exists in the scope of "; what+=_name;
200  throw Exception(what);
201  }
202 
203  node->_father=this;
204  _setOfNode.push_back(node);
205  //should we also set _modified flag for node ??
206  ComposedNode *iter=node->_father;
207  //set the _modified flag so that latter on edUpdateState (eventually called by isValid) refresh state
208  //better call it at end
209  modified();
210  return true;
211 }
212 
219 {
221  list<Node *>::iterator iter=find(_setOfNode.begin(),_setOfNode.end(),node);
222  if(iter!=_setOfNode.end())
223  {
224  _setOfNode.erase(iter);
225  modified();
226  }
227 }
228 
229 std::vector< std::list<Node *> > Bloc::splitIntoIndependantGraph() const
230 {
231  std::size_t sz(_setOfNode.size());
232  list<Node *>::const_iterator it=_setOfNode.begin();
233  for(;it!=_setOfNode.end();it++)
234  (*it)->_colour=White;
235  it=_setOfNode.begin();
236  std::vector< list<Node *> > ret;
237  while(it!=_setOfNode.end())
238  {
239  Node *start(*it); start->_colour=Grey;
240  ret.push_back(list<Node *>());
241  list<Node *>& ll(ret.back());
242  std::queue<Node *> fifo; fifo.push(start);
243  while(!fifo.empty())
244  {
245  Node *cur(fifo.front()); fifo.pop();
246  ll.push_back(cur);
247  //
248  OutGate *og(cur->getOutGate());
249  list<InGate *> og2(og->edSetInGate());
250  for(list<InGate *>::const_iterator it2=og2.begin();it2!=og2.end();it2++)
251  {
252  Node *cur2((*it2)->getNode());
253  if(cur2->_colour==White)
254  {
255  cur2->_colour=Grey;
256  fifo.push(cur2);
257  }
258  }
259  //
260  InGate *ig(cur->getInGate());
261  list<OutGate *> bl(ig->getBackLinks());
262  for(list<OutGate *>::const_iterator it3=bl.begin();it3!=bl.end();it3++)
263  {
264  Node *cur3((*it3)->getNode());
265  if(cur3->_colour==White)
266  {
267  cur3->_colour=Grey;
268  fifo.push(cur3);
269  }
270  }
271  }
272  for(it=_setOfNode.begin();it!=_setOfNode.end() && (*it)->_colour!=White;it++);
273  }
274  return ret;
275 }
276 
277 Node *Bloc::getChildByShortName(const std::string& name) const throw(YACS::Exception)
278 {
279  for (list<Node *>::const_iterator iter = _setOfNode.begin(); iter != _setOfNode.end(); iter++)
280  if ((*iter)->getName() == name)
281  return (*iter);
282  string what("node "); what+= name ; what+=" is not a child of Bloc "; what += getName();
283  throw Exception(what);
284 }
285 
287 {
288  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
289  {
290  if((*iter)->_state == YACS::DONE)continue;
291  if((*iter)->_state == YACS::DISABLED)continue;
292  return false;
293  }
294  return true;
295 }
296 
298 {
299  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
300  {
301  if((*iter)->_state == YACS::DONE)continue;
302  if((*iter)->_state == YACS::FAILED)continue;
303  if((*iter)->_state == YACS::DISABLED)continue;
304  if((*iter)->_state == YACS::ERROR)continue;
305  if((*iter)->_state == YACS::INTERNALERR)continue;
306  return false;
307  }
308  return true;
309 }
310 
311 bool Bloc::isNameAlreadyUsed(const std::string& name) const
312 {
313  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
314  if((*iter)->getName()==name)
315  return true;
316  return false;
317 }
318 
319 bool insertNodeChildrenInSet(Node *node, std::set<Node *>& nodeSet)
320 {
321  bool verdict=true;
322  list<Node *> outNodes=node->getOutNodes();
323  for (list<Node *>::iterator iter=outNodes.begin();iter!=outNodes.end(); iter++)
324  {
325  verdict=(nodeSet.insert(*iter)).second;
326  if (verdict) verdict = insertNodeChildrenInSet((*iter),nodeSet);
327  }
328  return verdict;
329 }
330 
337 {
338  set<Node *> currentNodesToTest;
339  //don't insert node to test in set.
340  //If it is present after insertion of connected nodes we have a loop
341  //collect all connected nodes
342  insertNodeChildrenInSet(node,currentNodesToTest);
343  //try to insert node
344  if(!(currentNodesToTest.insert(node)).second)
345  throw Exception("Cycle has been detected",1);
346 }
347 
348 std::vector< std::pair<OutGate *, InGate *> > Bloc::getSetOfInternalCFLinks() const
349 {
350  vector< pair<OutGate *, InGate *> > ret;
351  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
352  {
353  list<InGate *> outCFLinksOfCurNode=(*iter)->_outGate.edSetInGate();
354  for(list<InGate *>::iterator iter2=outCFLinksOfCurNode.begin();iter2!=outCFLinksOfCurNode.end();iter2++)
355  ret.push_back(pair<OutGate *, InGate *>(&(*iter)->_outGate,*iter2));
356  }
357  return ret;
358 }
359 
369 {
370  DEBTRACE("Bloc::updateStateOnFinishedEventFrom: " << node->getName());
371  //ASSERT(node->_father==this)
373  {
375  if(!areAllSubNodesDone())
376  {
378  return YACS::ABORT;
379  }
380  return YACS::FINISH;//notify to father node that 'this' has becomed finished.
381  }
382  //more job to do in 'this' bloc
383  //Conversion exceptions can be thrown so catch them to control errors
384  try
385  {
386  //notify the finished node to propagate to its following nodes
387  node->exForwardFinished();
388  }
389  catch(YACS::Exception& ex)
390  {
391  //The node has failed to propagate. It must be put in error
392  DEBTRACE("Bloc::updateStateOnFinishedEventFrom: " << ex.what());
393  // notify the node it has failed
394  node->exForwardFailed();
396  return YACS::ABORT;
397  }
398  return YACS::NOEVENT;//no notification to father needed because from father point of view nothing happened.
399 }
400 
402 
407 {
408  node->exForwardFailed();
410  {
412  if(!areAllSubNodesDone()){
414  return YACS::ABORT;
415  }
416  return YACS::FINISH;//notify to father node that 'this' has becomed finished.
417  }
418  return YACS::NOEVENT;
419 }
420 
421 void Bloc::writeDot(std::ostream &os) const
422 {
423  os << " subgraph cluster_" << getId() << " {\n" ;
424  list<Node *>nodes=getChildren();
425  for(list<Node *>::const_iterator iter=nodes.begin();iter!=nodes.end();iter++)
426  {
427  (*iter)->writeDot(os);
428  string p=(*iter)->getId();
429  //not connected node
430  if((*iter)->_inGate._backLinks.size() == 0) os << getId() << " -> " << p << ";\n";
431  list<Node *>outnodes = (*iter)->getOutNodes();
432  for(list<Node *>::const_iterator itout=outnodes.begin();itout!=outnodes.end();itout++)
433  {
434  os << p << " -> " << (*itout)->getId() << ";\n";
435  }
436  }
437  os << "}\n" ;
438  os << getId() << "[fillcolor=\"" ;
440  os << getColorState(state);
441  os << "\" label=\"" << "Bloc:" ;
442  os << getQualifiedName() <<"\"];\n";
443 }
444 
445 void Bloc::accept(Visitor* visitor)
446 {
447  visitor->visitBloc(this);
448 }
449 
455 {
456  std::vector< std::list<Node *> > r(splitIntoIndependantGraph());
457  int ret(0);
458  for(std::vector< std::list<Node *> >::const_iterator it=r.begin();it!=r.end();it++)
459  {
460  SetOfPoints sop(*it);
461  sop.simplify();
462  ret+=sop.getMaxLevelOfParallelism();
463  }
464  return ret;
465 }
466 
468 {
470  LinkInfo info(I_CF_USELESS);
471  initComputation();
473  std::set< std::pair<Node *, Node *> > linksToKill(info.getInfoUselessLinks());
474  for(std::set< std::pair<Node *, Node *> >::const_iterator it=linksToKill.begin();it!=linksToKill.end();it++)
475  edRemoveCFLink((*it).first,(*it).second);
477 }
478 
480 {
481  delete _fwLinks;//Normally useless
482  delete _bwLinks;//Normally useless
483  _fwLinks=new map<Node *,set<Node *> >;
484  _bwLinks=new map<Node *,set<Node *> >;
485 
486  //a set to store all CF links : used to find fastly if two nodes are connected
487  std::set< std::pair< Node*, Node* > > links;
488 
489  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
490  {
491  Node* n1=*iter;
492  std::list<InGate *> ingates=n1->getOutGate()->edSetInGate();
493  for(std::list<InGate *>::const_iterator it2=ingates.begin();it2!=ingates.end();it2++)
494  {
495  //CF link : n1 -> (*it2)->getNode()
496  Node* n2=(*it2)->getNode();
497  links.insert(std::pair< Node*, Node* >(n1,n2));
498  std::set<Node *> bwn1=(*_bwLinks)[n1];
499  std::set<Node *> fwn1=(*_fwLinks)[n1];
500  std::set<Node *> fwn2=(*_fwLinks)[n2];
501  std::set<Node *> bwn2=(*_bwLinks)[n2];
502  std::pair<std::set<Node*>::iterator,bool> ret;
503  for(std::set<Node *>::const_iterator iter2=bwn1.begin();iter2!=bwn1.end();iter2++)
504  {
505  for(std::set<Node *>::const_iterator it3=fwn2.begin();it3!=fwn2.end();it3++)
506  {
507  ret=(*_fwLinks)[*iter2].insert(*it3);
508  if(ret.second==false)
509  {
510  //dependency already exists (*iter2) -> (*it3) : if a direct link exists it's a useless one
511  if(links.find(std::pair< Node*, Node* >(*iter2,*it3)) != links.end())
512  info.pushUselessCFLink(*iter2,*it3);
513  }
514  }
515  ret=(*_fwLinks)[*iter2].insert(n2);
516  if(ret.second==false)
517  {
518  //dependency already exists (*iter2) -> n2 : if a direct link exists it's a useless one
519  if(links.find(std::pair< Node*, Node* >(*iter2,n2)) != links.end())
520  info.pushUselessCFLink(*iter2,n2);
521  }
522  }
523  for(std::set<Node *>::const_iterator it3=fwn2.begin();it3!=fwn2.end();it3++)
524  {
525  ret=(*_fwLinks)[n1].insert(*it3);
526  if(ret.second==false)
527  {
528  //dependency already exists n1 -> *it3 : if a direct link exists it's a useless one
529  if(links.find(std::pair< Node*, Node* >(n1,*it3)) != links.end())
530  info.pushUselessCFLink(n1,*it3);
531  }
532  }
533  ret=(*_fwLinks)[n1].insert(n2);
534  if(ret.second==false)
535  {
536  //dependency already exists n1 -> n2 : it's a useless link
537  info.pushUselessCFLink(n1,n2);
538  }
539 
540  for(std::set<Node *>::const_iterator iter2=fwn2.begin();iter2!=fwn2.end();iter2++)
541  {
542  (*_bwLinks)[*iter2].insert(bwn1.begin(),bwn1.end());
543  (*_bwLinks)[*iter2].insert(n1);
544  }
545  (*_bwLinks)[n2].insert(bwn1.begin(),bwn1.end());
546  (*_bwLinks)[n2].insert(n1);
547  }
548  }
549 }
550 
564 {
567 }
568 
570 {
572  delete _fwLinks; _fwLinks=0;
573  delete _bwLinks; _bwLinks=0;
574 }
575 
589 void Bloc::checkControlDependancy(OutPort *start, InPort *end, bool cross,
590  std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
591  std::vector<OutPort *>& fwCross,
592  std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
593  LinkInfo& info) const
594 {
595  if(!cross)
596  {
597  Node *startN=isInMyDescendance(start->getNode());
598  Node *endN=isInMyDescendance(end->getNode());
599  if(startN==endN)
600  bw[(ComposedNode *)this].push_back(start);
601  else if(areLinked(startN,endN,true))
602  fw[(ComposedNode *)this].push_back(start);
603  else
604  if(areLinked(startN,endN,false))
605  bw[(ComposedNode *)this].push_back(start);
606  else
607  info.pushErrLink(start,end,E_UNPREDICTABLE_FED);
608  }
609  else//DFDS detected
611  fwCross.push_back(start);
612  else
613  info.pushErrLink(start,end,E_DS_LINK_UNESTABLISHABLE);
614 }
615 
617 
625 bool Bloc::areLinked(Node *start, Node *end, bool fw) const
626 {
627  set<Node *>& nexts=fw ? (*_fwLinks)[start] : (*_bwLinks)[start];
628  return nexts.find(end)!=nexts.end();
629 }
630 
632 
640 {
641  set<Node *>& nexts=(*_fwLinks)[start];
642  set<Node *>& preds=(*_bwLinks)[start];
643  return nexts.find(end)==nexts.end() && preds.find(end)==preds.end();
644 }
645 
647 
654 void Bloc::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
655 {
656  if(alreadyFed==FREE_ST || alreadyFed==FED_ST)
657  {
658  map<Node *,list <OutPort *> > classPerNodes;
659  for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++)
660  classPerNodes[isInMyDescendance((*iter1)->getNode())].push_back(*iter1);
661  set<Node *> allNodes;
662  for(map<Node *,list <OutPort *> >::iterator iter2=classPerNodes.begin();iter2!=classPerNodes.end();iter2++)
663  allNodes.insert((*iter2).first);
664  vector<Node *> okAndUseless1,useless2;
665  seekOkAndUseless1(okAndUseless1,allNodes);
666  seekUseless2(useless2,allNodes);//after this point allNodes contains collapses
667  verdictForOkAndUseless1(classPerNodes,end,okAndUseless1,alreadyFed,direction,info);
668  verdictForCollapses(classPerNodes,end,allNodes,alreadyFed,direction,info);
669  verdictForOkAndUseless1(classPerNodes,end,useless2,alreadyFed,direction,info);
670  }
671  else if(alreadyFed==FED_DS_ST)
672  for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++)
673  info.pushErrLink(*iter1,end,E_COLLAPSE_DFDS);
674 }
675 
677 {
678  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
679  {
680  (*iter)->_colour=White;
681  (*iter)->getInGate()->exReset();
682  (*iter)->getOutGate()->exReset();
683  }
684 }
685 
695 void Bloc::verdictForOkAndUseless1(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end,
696  const std::vector<Node *>& candidates, unsigned char& alreadyFed,
697  bool direction, LinkInfo& info)
698 {
699  for(vector<Node *>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
700  {
701  const list<OutPort *>& mySet=(*pool.find(*iter)).second;
702  if(mySet.size()==1)
703  {
704  if(alreadyFed==FREE_ST)
705  {
706  alreadyFed=FED_ST;//This the final choice. General case !
707  if(!direction)
708  info.pushInfoLink(*(mySet.begin()),end,I_BACK);
709  }
710  else if(alreadyFed==FED_ST)
711  info.pushInfoLink(*(mySet.begin()),end,direction ? I_USELESS : I_BACK_USELESS);//Second or more turn in case of alreadyFed==FREE_ST before call of this method
712  }
713  else
714  {
715  if(dynamic_cast<ElementaryNode *>(*iter))
716  {
717  WarnReason reason;
718  if(alreadyFed==FREE_ST)
719  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
720  else if(alreadyFed==FED_ST)
722  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
723  info.pushWarnLink(*iter2,end,reason);
724  }
725  else
726  ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model!
727  }
728  }
729 }
730 
740 void Bloc::verdictForCollapses(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end,
741  const std::set<Node *>& candidates, unsigned char& alreadyFed,
742  bool direction, LinkInfo& info)
743 {
744  info.startCollapseTransac();
745  for(set<Node *>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
746  {
747  const list<OutPort *>& mySet=(*pool.find(*iter)).second;
748  if(mySet.size()==1)
749  {
750  if(alreadyFed==FREE_ST)
751  info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE : W_BACK_COLLAPSE);
752  else if(alreadyFed==FED_ST)
753  info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE_AND_USELESS : W_BACK_COLLAPSE_EL_AND_USELESS);
754  }
755  else
756  {
757  if(dynamic_cast<ElementaryNode *>(*iter))
758  {
759  WarnReason reason;
760  if(alreadyFed==FREE_ST)
761  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
762  else if(alreadyFed==FED_ST)
764  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
765  info.pushWarnLink(*iter2,end,reason);
766  }
767  else
768  {
769  ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model!
770  WarnReason reason;
771  if(alreadyFed==FREE_ST)
772  reason=direction ? W_COLLAPSE : W_BACK_COLLAPSE;
773  else if(alreadyFed==FED_ST)
775  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
776  info.pushWarnLink(*iter2,end,reason);
777  }
778  }
779  }
780  if(!candidates.empty())
781  if(alreadyFed==FREE_ST)
782  alreadyFed=FED_ST;
783  info.endCollapseTransac();
784 }
785 
791 void Bloc::seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const
792 {
793  set<Node *>::iterator iter=allNodes.begin();
794  while(iter!=allNodes.end())
795  {
796  set<Node *>& whereToFind=(*_bwLinks)[*iter];
797  std::set<Node *>::iterator iter2;
798  for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++)
799  if((*iter)!=(*iter2))
800  if(whereToFind.find(*iter2)==whereToFind.end())
801  break;
802  if(iter2!=allNodes.end())
803  iter++;
804  else
805  {
806  okAndUseless1.push_back((*iter));
807  allNodes.erase(iter);
808  iter=allNodes.begin();
809  }
810  }
811 }
812 
817 void Bloc::seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const
818 {
819  set<Node *>::iterator iter=allNodes.begin();
820  while(iter!=allNodes.end())
821  {
822  set<Node *>& whereToFind=(*_fwLinks)[*iter];
823  std::set<Node *>::iterator iter2;
824  for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++)
825  if((*iter)!=(*iter2))
826  if(whereToFind.find(*iter2)==whereToFind.end())
827  break;
828  if(iter2!=allNodes.end())
829  {
830  iter++;
831  }
832  else
833  {
834  useless2.push_back((*iter));
835  allNodes.erase(iter);
836  iter=allNodes.begin();
837  }
838  }
839 }
840 
844 void Bloc::updateWithNewFind(const std::vector<Node *>& path, std::map<Node *, std::set<Node *> >& fastFinder)
845 {
846  if(path.size()>=3)
847  {
848  vector<Node *>::const_iterator iter=path.begin(); iter++;
849  vector<Node *>::const_iterator iter2=path.end(); iter2-=1;
850  for(;iter!=iter2;iter++)
851  fastFinder[*iter].insert(*(iter+1));
852  }
853 }
854 
858 void Bloc::findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info)
859 {
860  unsigned maxSize=0;
861  list< vector<Node *> >::const_iterator whereToPeerAt;
862  for(list< vector<Node *> >::const_iterator iter=res.begin();iter!=res.end();iter++)
863  if((*iter).size()>maxSize)
864  {
865  maxSize=(*iter).size();
866  whereToPeerAt=iter;
867  }
868  //
869  if(maxSize>1)
870  {
871  vector<Node *>::const_iterator iter2=(*whereToPeerAt).begin();
872  map<Node *,bool>::iterator iter4;
873  set<Node *> searcher(iter2+1,(*whereToPeerAt).end());//to boost research
874  for(;iter2!=((*whereToPeerAt).end()-2);iter2++)
875  {
876  list< pair<InGate *,bool> >& nexts=(*iter2)->getOutGate()->edMapInGate();
877  for(list< pair<InGate *,bool> >::iterator iter4=nexts.begin();iter4!=nexts.end();iter4++)
878  if((*iter4).first->getNode()!=*(iter2+1))
879  if(searcher.find((*iter4).first->getNode())!=searcher.end())
880  info.pushUselessCFLink(*iter2,(*iter4).first->getNode());
881  searcher.erase(*iter2);
882  }
883  }
884 }