Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Implementation of multiple mapping algorithm possibility.
[jaceP2P.git] / src / jaceP2P / JaceSuperNodeServer.java
1 package jaceP2P;
2
3 import java.rmi.RemoteException;
4 import java.rmi.server.UnicastRemoteObject;
5 import java.util.ArrayList;
6 import java.util.Vector;
7
8 import and.Mapping.Algo;
9 import and.Mapping.DefaultMapping;
10 import and.Mapping.GNode;
11 import and.Mapping.GTask;
12 import and.Mapping.Graph;
13 import and.Mapping.Grid;
14 import and.Mapping.LSM;
15 import and.Mapping.QM;
16 import and.Mapping.Simple;
17 import and.Mapping.Utils;
18
19
20 public class JaceSuperNodeServer extends UnicastRemoteObject implements
21                 JaceSuperNodeInterface {
22         private static final long serialVersionUID = 1L;
23
24         // Attributes
25         private int beat;
26         private ArrayList<GNode> gnodes = null;
27         private ArrayList<Algo> algos = null ;
28         private int count = 0 ;
29         private boolean inDemand = false, operating = false, authorized = false ;
30 //      private boolean daemonListChange ;
31         
32         // Constructors
33
34         public JaceSuperNodeServer(int timeBeat) throws RemoteException {
35                 super() ;
36                 beat = timeBeat ;
37                 gnodes = new ArrayList<GNode>() ;
38                 algos = new ArrayList<Algo>() ;
39 //              daemonListChange = true ;
40         }
41
42         public int getSuperNodeBeat() throws RemoteException {
43                 return beat;
44         }
45
46         public Vector<?> sendStub(String IP, int port, JaceSuperNodeInterface stub)
47                         throws RemoteException {
48                 SuperNodeListe.Instance().addStubOf(IP, port, stub);
49                 System.out.println("Added new superNode (" + IP
50                                 + ") to list and return List");
51                 return SuperNodeListe.Instance().getListe();
52         }
53
54         public void updateCountNode(String IP, int nb) throws RemoteException {
55                 SuperNodeListe.Instance().modifCountNode(IP, nb);
56                 // System.out.println( "SuperNode " + IP + " has registered " + nb +
57                 // " Daemons" ) ;
58                 SuperNodeListe.Instance().viewAll();
59         }
60
61         public void sendSurplus(Vector<?> nodes, ArrayList<GNode> _gnodes) throws RemoteException {
62                 System.out.println("Recieved " + nodes.size() + " nodes");
63
64                 for (int i = 0; i < nodes.size(); i++) {
65                         Register.Instance().getListe().add((Node) nodes.elementAt(i));
66
67                         System.out.println("Adding "
68                                         + ((Node) nodes.elementAt(i)).getName());
69
70                         try {
71                                 ((Node) nodes.elementAt(i)).getStub().updateHeart(
72                                                 LocalHost.Instance().getSuperNodeStub());
73                                 int index = SuperNodeListe.Instance().existSuperNode(
74                                                 LocalHost.Instance().getIP());
75                                 ((SuperNodeData) SuperNodeListe.Instance().getListe()
76                                                 .get(index))
77                                                 .setNbOfNodes(Register.Instance().getSize());
78                                 new ForwardCount().start();
79                         } catch (Exception e) {
80                                 System.err.println("Error changing Server in SendSurplus : "
81                                                 + e);
82                         }
83                 }
84                 
85                 /** Updating gnodes **/
86                 if( _gnodes != null )
87                 {
88                         gnodes = _gnodes ;
89                 }
90         }
91
92         public void setToken() throws RemoteException {
93                 System.out.println("I got Token");
94
95                 TokenThread.Instance().setToken();
96
97                 try {
98                         HeartBeatSNode.Instance().getServer().beating(true);
99
100                         System.out.println("Put token to true");
101                 } catch (Exception e) {
102                         System.err
103                                         .println("Unable to heartBeat the next SuperNode with the new Token : "
104                                                         + e);
105                 }
106         }
107
108         public void updateHeart(JaceSuperNodeInterface stub) throws RemoteException {
109                 System.out.println("I change to ping a superNode");
110
111                 HeartBeatSNode.Instance().setServer(stub);
112         }
113
114         public synchronized void removeSuperNode(SuperNodeData d)
115                         throws RemoteException {
116                 SuperNodeListe.Instance().removeSuperNode(d);
117         }
118
119         /****************************************************/
120         /****************************************************/
121
122         // Register a Daemon in the Register.Instance() of the SuperNode
123         public synchronized void workerRegistering(JaceInterface workerStub,
124                         String workerIP, String workerName, int port, GNode g)
125                         throws RemoteException {
126                 System.out.println("CONNECTION of " + workerName);
127
128                 // Create the node
129                 Node noeud = new Node(workerStub);
130                 noeud.setName(workerName);
131                 noeud.setIP(workerIP);
132                 noeud.setAliveFlag(true);
133                 noeud.setAliveTime();
134                 noeud.setPort(port);
135                 noeud.setAppliName(null);
136                 noeud.setNbOfBeats(0);
137                 noeud.setId( count ) ;
138                 noeud.setId( Long.parseLong( workerIP.replace( ".", "" ) ) ) ;
139
140                 g.setNode( noeud ) ;
141                 g.setId( noeud.getId() ) ;
142                 g.setMapped( false ) ;
143                 
144                 workingOnGnodes() ;
145                 
146                 gnodes.add( g ) ;
147                 
148 //              daemonListChange = true ;
149
150                 // Insert the node in the Register.Instance() of the Super Node
151                 Register.Instance().addNode(noeud);
152
153                 // Register.Instance().viewAll() ;
154                 // SuperNodeListe.Instance().viewAll() ;
155
156                 // Inform the other superNode and tell them the nb of Daemon I have
157                 // registered
158                 int index = SuperNodeListe.Instance().existSuperNode(
159                                 LocalHost.Instance().getIP());
160
161                 ((SuperNodeData) SuperNodeListe.Instance().getListe().get(index))
162                                 .setNbOfNodes(Register.Instance().getSize());
163                 SuperNodeListe.Instance().forwardCountNode();
164                 
165                 authorized = true ;
166                 SuperNodeListe.Instance().addGNode( g ) ;
167                 authorized = false ;
168                 
169                 operating = false ;
170         }
171
172         /****************************************************/
173         /****************************************************/
174
175         // HeartBeat that detects if a Daemon is dead or alive
176         public void beating(JaceInterface stub) throws RemoteException {
177                 Node noeud = Register.Instance().getNodeOfStub(stub);
178
179                 if (noeud != null) {
180                         noeud.setAliveFlag(true);
181                         noeud.setAliveTime();
182                         noeud.incrementNbOfBeats();
183                         // -- sm modif
184                         // System.out.println( noeud.getName() + " is pinging me" ) ;
185                 } else {
186                         // System.out.println( noeud.getName() +
187                         // ".................. is not in my list" ) ;
188                 }
189         }
190
191         // HeartBeat that detects if a Super Node is dead or alive
192         public void beating(boolean token) throws RemoteException {
193                 ScanThreadSuperNode.Instance().setAliveTime();
194                 ScanThreadSuperNode.Instance().setToken(token);
195                 // -- sm modif
196                 // System.out.println( "Super Node is pinging me" ) ;
197         }
198
199
200         /*********************************/
201         /** Mapping !! Sébastien Miquée **/
202         /*********************************/
203
204         /**
205          * Search and return to the requester spawner a register containing
206          * computation nodes plus some extra nodes if needed. This method requires
207          * as parameters the mapping algorithm choice and its parameters, and the
208          * amount of requested nodes and the task to be used, in order to 
209          * construct the tasks graph.
210          * @param spawnerIP IP of the requester
211          * @param nbTasks Amount of tasks
212          * @param t Tasks to be executed
213          * @param nbNoeuds Total amount of requested nodes
214          * @param algo Identifier of the mapping algorithm
215          * @param paramAlgo Parameter of the mapping algorithm 
216          * 
217          * @author S&eacute;bastien Miqu&eacute;e        
218          */
219         @Override
220         public Register getRegisterSpawner(String spawnerIP, int nbTasks, Task t,
221                         int nbNoeuds, int algo, double paramAlgo) throws RemoteException {
222
223                 // Have we the correct application ?
224                 if( t == null ) {
225                         System.err.println( "Problem of class transmission!" ) ;
226                         return null ;
227                 }
228                 
229                 if( t.getDependencies( 0 ) == null )
230                 {
231                         System.err.println( "No redifinition of getDependencies() function!" ) ;
232                         return null ;
233                 }
234                 
235
236                 /** Creation of an empty new Register **/
237                 Register reg = new Register() ;
238
239                 workingOnGnodes() ;
240                 
241                 /** Initialization of Grid architecture (G5K for now) **/
242                 Grid grid = Utils.createGridG5k(gnodes);
243 //              grid.initClusters();
244                 
245                 
246                 /** Informing about the grid heterogeneity **/
247                 System.out.println( "\nHeterogeneity of the grid : " + grid.getHeterogenityDegre() + "\n" ) ;
248                 
249
250                 /** Creation of tasks GTask **/
251                 ArrayList<GTask> ts = new ArrayList<GTask>();
252                 for( int i = 0; i < nbTasks; i++ ) {
253                         ts.add( new GTask( i ) ) ;
254                 }
255
256                 /** Research of dependencies **/
257                 for( int i = 0; i < nbTasks; i++ ) {
258                         int dep[] = null ;
259                         dep = t.getDependencies( i ) ;
260
261                         /** Adding dependencies to tasks **/
262                         for( int j = 0; j < dep.length; j++ ) {
263                                 if( dep[j] != -1 ) {
264                                         ts.get( i ).addDependance( ts.get( dep[ j ] ) ) ;
265                                 } else {
266                                         break ;
267                                 }
268                         }
269                 }
270                 
271                 /** Creation of the application interaction graph **/
272                 Graph graph = new Graph();
273
274                 for( int i = 0 ; i < ts.size() ; i++) 
275                 {
276                         graph.addGTask(ts.get(i));
277                 }
278
279                 // -- debug !
280                 // graph.print() ;
281
282                 // try {
283                 // Thread.sleep(10000) ;
284                 // } catch( Exception e ) {}
285
286                 // grid.print() ;
287                 // 
288                 // try {
289                 // Thread.sleep( 10000 ) ;
290                 // } catch( Exception e ) {}
291
292                 /** Selection of the mapping algorithm **/
293                 Algo al = null ;
294
295                 switch( algo ) {
296                 case 0:
297                         al = new Simple(graph, grid);
298                         break;
299                 case 1:
300                         al = new QM(graph, grid, paramAlgo);
301                         break;
302                 case 2:
303                         al = new LSM(graph, grid, paramAlgo);
304                         break;
305                 default:
306                         al = new DefaultMapping( graph, grid, gnodes ) ;
307                 }
308
309                 if (al != null) 
310                 {
311                         /** Launching the Mapping **/
312                         al.map();
313
314
315                         /** Creating the register **/
316                         ArrayList<GNode> ag = al.getMapping().getMappedGNodes();
317
318                         authorized = true ;
319                         
320                         for( int i = 0; i < ag.size(); i++ ) {
321                                 reg.addNode((Node) ag.get(i).getNode());
322                                 delGNodeFromList( (Node) ag.get(i).getNode(), 2, spawnerIP ) ;
323 //                              gnodes.remove(ag.get(i));
324 //                              Register.Instance().removeNode((Node) ag.get(i).getNode());
325                         }
326                         
327                         
328                         /** Searching extra nodes if any **/
329                         if( nbNoeuds > nbTasks )
330                         {
331                                 int nb = nbNoeuds - nbTasks ;
332                                 GNode sup = null ;
333                                 
334                                 for( int i = 0 ; i < nb ; i ++ )
335                                 {
336                                         sup = al.getOtherGNode( gnodes ) ;
337                                         reg.addNodeBeg( (Node) sup.getNode() ) ;
338                                         delGNodeFromList( (Node) sup.getNode(), 2, spawnerIP ) ;
339                                 }
340                         }
341                         
342                         authorized = false ;
343
344                         if (ag.size() != 0) {
345                                 SuperNodeListe.Instance().forwardCountNode();
346                         }
347                         
348                         /** Setting the algorithm's identifier **/
349                         al.setIdS( spawnerIP ) ;
350                         
351                         /** Adding the algorithm in the list **/
352                         algos.add( al ) ;
353
354                 } 
355                 
356 //              System.out.println( "Spawner returned reg: " + reg ) ;
357                 
358                 /** Mapping distribution over other SuperNodes */
359                 SuperNodeListe.Instance().setMapping( al ) ;
360                 
361                 operating = false ;
362                 
363                 /** Returning result **/
364                 return reg ;
365         }
366
367         
368         /**
369          * Suppress a node from the gnodes list if this node is free, or remove
370          * it from the Mapping class of the mapping algorithm if this node is
371          * a computation node. After having done the local suppression of the node
372          * it propagates the suppression to other SuperNodes.
373          * @param _n The fallen node
374          * @param _mode Choice of the list (0: gnodes, 1: mapping, 2:just mapped)
375          * 
376          * @author S&eacute;bastien Miqu&eacute;e        
377          */
378         @Override
379         public GNode delGNodeFromList( Node _n, int _mode, String _spawnerIp ) throws RemoteException
380         {
381                 GNode removedGNode = null ;
382                 
383                 if( _n != null )
384                 {       
385                         boolean free = false ;
386                         
387                         if( ! operating )
388                         {
389                                 workingOnGnodes() ;
390                                 free = true ;
391                         }
392                         
393                         /** The dead node is not in the mapping **/
394                         if( _mode == 0 || _mode == 2)
395                         {
396                                 for( int i = 0 ; i < gnodes.size() ; i++ )
397                                 {
398                                         if( ((Node)gnodes.get(i).getNode()).getId() == _n.getId() ) 
399                                         {
400                                                 removedGNode = gnodes.remove( i ) ;
401                                                 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
402                                                 break ;
403                                         }
404                                 }
405                         }
406                         
407                         /** The dead node is in the mapping **/
408                         if( _mode == 1 )
409                         {
410                                 /** Searching the algorithm **/ 
411                                 int idAlgo = searchAlgo( _spawnerIp ) ;
412                                 
413                                 if( idAlgo == -1 )
414                                 {
415                                         System.err.println( "No algorithm found for this Spawner!" ) ;
416                                         return null ;
417                                 }
418                                 
419                                 ArrayList<GNode> temp = algos.get( idAlgo ).getMapping().getMappedGNodes() ;
420                                 
421                                 for( int i = 0 ; i < temp.size() ; i++ )
422                                 {
423                                         if( ((Node)temp.get(i).getNode()).getId() == _n.getId() ) 
424                                         {
425                                                 removedGNode = temp.get( i ) ;
426                                                 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
427                                                 break ;
428                                         }
429                                 }       
430                         }
431                         
432                         /** Removing the dead node from the Grid **/
433                         if( _mode == 0 || _mode == 1 ) {
434                                 int idAlgo = searchAlgo( _spawnerIp ) ;
435                                 
436                                 if( idAlgo != -1 && _mode == 1 )
437                                 {
438                                         algos.get( idAlgo ).getGrid().removeGNode( removedGNode ) ;
439                                 }
440                         }
441                         
442                         /** Propagation of the deletion **/
443                         SuperNodeListe.Instance().removeGNode( removedGNode, _mode, _spawnerIp ) ;
444                         
445                         if( free )
446                         {
447                                 operating = false ;
448                         }
449                 
450                 }
451                 
452                 return removedGNode ;
453         }
454         
455         
456         /**
457          * Search the position of the mapping algorithm in the list.
458          * @param _id Identifier of the algorithm
459          * @return The position in the list
460          */
461         private int searchAlgo( String _id ) 
462         {
463                 int id = -1 ;
464                 
465                 for( int i = 0 ; i < algos.size() ; i++ )
466                 {
467                         if( algos.get( i ).getIdS().equals( _id ) )
468                         {
469                                 id = i ; 
470                                 break ;
471                         }
472                 }
473                 
474                 return id ;
475         }
476
477         /**
478          * Determine if this SuperNode can operate on the gnodes list.
479          * It asks other SuperNodes to know if their are working on this list
480          * and set the authorization, or not.
481          * 
482          * @author S&eacute;bastien Miqu&eacute;e        
483          */
484         private void workingOnGnodes()
485         {
486                 boolean tmp = true ;    
487                 
488                 inDemand = false ; 
489                 operating = false ;
490             
491                 while( ! operating )
492                 {
493                         inDemand = true ;
494                         tmp = true ;
495                         
496                         tmp = tmp && SuperNodeListe.Instance().workingOnGnodes() ;
497
498                         operating = tmp ;
499                         
500                         if( ! tmp )
501                         {
502                                 inDemand = false ;
503                                 
504                                 try {
505                                         Thread.sleep( 10 ) ;
506                                 } catch (InterruptedException e) {
507                                         e.printStackTrace();
508                                 }
509                         }
510                 }
511                 
512                 inDemand = false ;
513         }
514
515         /**
516          * Search and return a new node when one failed or when JaceP2P needs another
517          * one. For the first case, the given failed node should not be null, and
518          * null in the other case.
519          * @param _spawnerIP IP of the requester
520          * @param _deadNode The failed node
521          * 
522          * @author S&eacute;bastien Miqu&eacute;e
523          */
524         @Override
525         public Node getNewNode( String _spawnerIP, Node _deadNode ) throws RemoteException
526         {
527                 Node node = null ;
528                 GNode remp = null, gnode = null ;
529
530                 int idAlgo = searchAlgo( _spawnerIP ) ;
531                 
532                 if( idAlgo == -1 )
533                 {
534                         System.err.println( "No algorithm found for this Spawner!" ) ;
535                         return null ;
536                 }
537                 
538                 /** Can we use gnodes ?**/
539                 workingOnGnodes() ;
540                 
541                 if( _deadNode != null )
542                 {
543                         authorized = true ;
544                         
545                         gnode = delGNodeFromList( _deadNode, 1, _spawnerIP ) ;
546
547                         remp = algos.get( idAlgo ).replaceNode( gnode, gnodes ) ;
548                 
549                         if( remp != null )
550                         {
551                                 System.out.println( "Replacing node found." ) ;
552                                 
553                                 remp.setMapped( true ) ;
554                                 
555                                 delGNodeFromList( (Node) remp.getNode(), 2, _spawnerIP ) ;
556                                 
557                                 authorized = false ;
558                                 
559                                 SuperNodeListe.Instance().forwardCountNode();
560                         } else {
561                                 System.err.println( "Replacing node not found !!" ) ;
562                         }
563                 } else {
564                         remp = algos.get( idAlgo ).getOtherGNode( gnodes ) ;
565                         
566                         if( remp != null )
567                         {
568                                 System.out.println( "Other new node found." ) ;
569
570                                 remp.setMapped( true ) ;
571                                 
572                                 authorized = true ;
573                                 
574                                 delGNodeFromList( (Node) remp.getNode(), 2, _spawnerIP ) ;
575                                 
576                                 authorized = false ;
577                                 
578                                 SuperNodeListe.Instance().forwardCountNode();
579                         } else {
580                                 System.err.println( "Other new node not found !!" ) ;
581                         }
582                 }
583                 
584                 if( remp != null )
585                 {
586                         node = (Node) remp.getNode() ;
587                 }
588                 
589                 
590                 /** Updating all mapping **/
591                 updateMappedNode( gnode, remp, _spawnerIP ) ;
592                 propagateReplaceNode( gnode, remp, _spawnerIP ) ;
593                 
594                 
595                 /** Free the gnodes use **/
596                 operating = false ;
597                 
598                 return node ;
599         }
600         
601         
602         /**
603          * Replace a failed GNode in the mapping by another one.
604          * This method is called by the SuperNodeList, to broadcast the modification.
605          * @param _dead The failed node
606          * @param _remp The replacing node
607          * 
608          * @author S&eacute;bastien Miqu&eacute;e
609          */
610         @Override
611         public void updateMappedNode( GNode _dead, GNode _remp, String _spawnerIP ) 
612         {
613                 if( _remp != null )
614                 {
615                         int pos = 0 ;
616                         
617                         int idAlgo = searchAlgo( _spawnerIP ) ;
618                         
619                         if( idAlgo == -1 )
620                         {
621                                 System.err.println( "No algorithm found for this Spawner!" ) ;
622                                 return ;
623                         }
624                 
625                         pos = algos.get( idAlgo ).getMapping().getIdOfAssociation( _dead ) ;
626                 
627                         if( pos != -1 )
628                         {
629                                 /** Changing the node in the mapping **/
630                                 algos.get( idAlgo ).getMapping().getMapping().get( pos ).setGNode( _remp ) ;
631                                 
632                                 System.out.println( "Succesfully replacing the fallen node in the mapping." ) ;
633                         }               
634                         
635                         /** Changing the status in the grid **/
636                         algos.get( idAlgo ).getGrid().setMappedStatus( _remp, true ) ;
637                 
638                         algos.get( idAlgo ).updateGrid() ;
639                 } else {
640                         System.err.println( "The new GNode is null!" ) ;
641                 }
642         }
643
644         
645         /**
646          * Inform all SuperNodes of the replacement of a failed computing node.
647          * @param _dead The failed node
648          * @param _remp The replacing node
649          * 
650          * @author S&eacute;bastien Miqu&eacute;e        
651          */
652         private void propagateReplaceNode( GNode _dead, GNode _remp, String _spawnerIP ) throws RemoteException
653         {
654                 if( _remp != null )
655                 {       
656                         SuperNodeListe.Instance().propagateReplaceNode( _dead, _remp, _spawnerIP ) ;
657                 }
658         }
659
660         /**********************************************************/
661         /**********************************************************/
662
663         
664         @Override
665         /**
666          * Add a new node in the list.
667          * @param _g The new node
668          *
669          * @author S&eacute;bastien Miqu&eacute;e        
670          */
671         public void addGNode( GNode _g ) throws RemoteException 
672         {
673                 if( _g != null )
674                 {
675                         boolean free = false ;
676                         
677                         if( ! operating )
678                         {
679                                 workingOnGnodes() ;
680                                 free = true ;
681                         }       
682                         
683                         gnodes.add( _g ) ;
684                         
685                         if( free )
686                                 operating = false ;
687                 }
688         }
689         
690
691 //      @Override
692 //      public void removeGNode( GNode _g ) throws RemoteException 
693 //      {
694 //              if( _g != null )
695 //              {
696 //                      boolean free = false ;
697 //                      
698 //                      if( ! operating )
699 //                      {
700 //                              workingOnGnodes() ;
701 //                              free = true ;
702 //                      }
703 //                      
704 //                      for( int i = 0 ; i < gnodes.size() ; i++ )
705 //                      {
706 //                              if( ((Node)gnodes.get(i).getNode()).getId() == ((Node)_g.getNode()).getId() ) 
707 //                              {
708 //                                      gnodes.remove( i ) ;
709 //                                      Register.Instance().removeNodeOfName( _g.getName() ) ;
710 //                                      break ;
711 //                              }
712 //                      }
713 //                      
714 //                      if( free )
715 //                              operating = false ;
716 //              }
717 //              
718 //      }
719         
720
721         /**
722          * Set the local mapping with another done on an other SuperNode.
723          * @param _al The new mapping
724          * 
725          * @author S&eacute;bastien Miqu&eacute;e
726          */
727         @Override
728         public void setMapping( Algo _al ) throws RemoteException 
729         {
730                 if( searchAlgo( _al.getIdS() ) == -1 )
731                         algos.add( _al ) ;                      
732         }
733
734         
735         @Override
736         /**
737          * Allow or deny the use of operations on the gnodes list, in order to
738          * do a mapping operation.
739          * @return The authorization or not to block gnodes
740          * 
741          * @author S&eacute;bastien Miqu&eacute;e
742          */
743         public boolean blockForMapping() throws RemoteException
744         {
745                 while( inDemand )
746                 {
747                         try {
748                                 Thread.sleep( 10 ) ;
749                         } catch (InterruptedException e) {
750                                 e.printStackTrace();
751                         }
752                 }
753                 
754                 if( operating && ! authorized )
755                 {
756                         return false ;
757                 } else {
758                         return true ;
759                 }
760         }
761
762         /**
763          * Return the array containing the current not mapped nodes available.
764          * @return The array of available nodes
765          * 
766          * @author S&eacute;bastien Miqu&eacute;e 
767          */
768         @Override
769         public ArrayList<GNode> getGNodes() throws RemoteException 
770         {
771                 return gnodes ;
772         }
773         
774         
775         /**
776          * Remove a mapping algorithm of the algorithms list.
777          * @param _id The algorithm identifier
778          * @param _mode Indicate if the information should be transmitted
779          * 
780          * @author S&eacute;bastien Miqu&eacute;e
781          */
782         public void removeAlgo( String _id, int _mode ) throws RemoteException
783         {
784                 int i ;
785                 
786                 i = searchAlgo( _id ) ;
787                 
788                 if( i != -1 )
789                 {
790                         algos.remove( i ) ;
791                         
792                         if( _mode == 0 )
793                         {
794                                 SuperNodeListe.Instance().removeAlgo( _id ) ;
795                         }
796                 }
797         }
798         
799 }
800
801 /** ! **/