next up previous contents
suivant: TraceTracer.java monter: Package dataStructures précédent: Task.java   Table des matières

Operation.java


package buffalo.dataStructures;

/**
  Classe d&eacute;crivant une <CODE>Op&eacute;ration</CODE> 
  &eacute;l&eacute;mentaire d'une <CODE>T&acirc;che</CODE> 
  sur un <CODE>Buffer</CODE>.
  <BR>
  <BR>
  On peut consid&eacute;rer qu'une <CODE>Op&eacute;ration</CODE> 
  est muni de tous les attributs suivants&nbsp;:
  <UL>
  <LI>
  Une <CODE>T&acirc;che</CODE>T</CODE> qui l'ex&eacute;cute, 
  cette <CODE>T&acirc;che</CODE> sera ici appell&eacute;e 
  <CODE>activeTask</CODE>.
  </LI>
  <LI>
  Un <CODE>Buffer</CODE> <CODE>B</CODE> vers lequel s'effectue cette 
  <CODE>Op&eacute;ration</CODE>.
  </LI>
  <LI>
  Une <CODE>T&acirc;che</CODE> <CODE>T'</CODE>qui partage le 
  <CODE>Buffer</CODE> avec <CODE>T</CODE>, appel&eacute;e 
  dans les m&eacute;thodes <CODE>PassiveTask</CODE>.
  </LI>
  <LI>
  Un <CODE>rang&nbsp;n</CODE>dans l'ordre d'ex&eacute;cution, 
  marquant une contrainte de pr&eacute;c&eacute;dence 
  vis-&agrave;-vis des contraintes de <CODE>rang</CODE> 
  sup&eacute;rieur. 
  Le successeur imm&eacute;diat, donc de <CODE>rang&nbsp;(n+1)</CODE>, 
  est appel&eacute; ici <CODE>nextFixedOperation</CODE>; on devine 
  que le pr&eacute;d&eacute;cesseur imm&eacute;diat, 
  de <CODE>rang&nbsp;(n-1)</CODE>, est appel&eacute; 
  <CODE>previousFixedOperation</CODE>.
  </LI>  
  <LI>
  Un cha&icirc;nage vers une <CODE>Op&eacute;ration</CODE> 
  not&eacute;e <CODE>o'</CODE>, et telle que si nous notons 
  l'<CODE>Op&eacute;ration</CODE> courante <CODE>o</CODE>, des 
  contraintes li&eacute;es aux dimensions des <CODE>Buffers</CODE> 
  ou &agrave; l'ordre des <CODE>Op&eacute;rations</CODE> ont pour 
  cons&eacute;quence le fait que <CODE>o</CODE> devra s'ex&eacute;cuter 
  avant <CODE>o'</CODE>. <CODE>o'</CODE> est ici d&eacute;sign&eacute; 
  comme &eacute;tant la <CODE>nextBufferedOperation</CODE> de <CODE>o</CODE>, 
  tout comme <CODE>o</CODE> est la <CODE>previousBufferedOperation</CODE> 
  de <CODE>o'</CODE>.
  </LI>
  <LI>
  Comme de m&ecirc;me il existe deux types de contraintes&nbsp;: de 
  <CODE>fullBuffer</CODE> et de <CODE>emptyBuffer</CODE>, un attribut 
  permet de savoir si la contrainte de pr&eacute;cedence 
  mentionn&eacute;e ci-dessus est pour cette <CODE>Op&eacute;ration</CODE> 
  une contrainte de <CODE>fullBuffer</CODE> ou non.
  </LI>
  </UL>
  <BR>
  
 */

public class Operation
{
    /*
      Buffer sur lequel s'effectue l'op&eacute;ration
    */

    private Buffer buffer;

    /*
      T&acirc;che effectuant cette op&eacute;ration
    */

    private Task activeTask;

    /*
      T&acirc;che li&eacute;e &agrave; activeTask par un le Buffer de 
      l'op&eacute;ration courante
     */

    private Task passiveTask;

    /*
      Index de l'operation courante
    */

    private int indexOfMe;

    /*
      Index de l'op&eacute;ration B li&eacute;e &agrave; celle de 
      l'instance courante A par une relation de famine ou d'interblocage 
      telle que B doit s'ex&eacute;cuter apr&egrave;s A
    */

    private Operation nextBufferedOperation;

    /*
      R&eacute;ciproque de la m&eacute;thode pr&eacute;c&eacute;dente
    */

    private Operation previousBufferedOperation;
    
    /*
      Image par N de this.
     */
    
    private int myImageByN;

    /*--------------------------------------------------------------------------------------*/

    /*
      Inutile en dehors du package... 
     */

    Operation(int indexOfBuffer, int indexOfTask, int indexOfMe)
    {
	this.buffer = Buffer.get(indexOfBuffer);
	this.activeTask = Task.get(indexOfTask);
	this.passiveTask = Buffer.get(indexOfBuffer).getOtherTask(this.activeTask.getIndex());
	//Si l'op&eacute;ration n'est pas conforme aux buffers connect&eacute;s. 
	if(passiveTask==null)
	    {
		System.out.println("***********\n" + 
				   "WARNING : \n" + 
				   "Buffer " + 
				   indexOfBuffer + 
				   " is not connected to task " + 
				   indexOfTask + 
				   "\n***********\n" );
	    }
	this.indexOfMe = indexOfMe;
	myImageByN = this.buffer.getNbInversedN(this.activeTask);
	this.buffer.addOperationToN(this, this.activeTask);
    }

    /*--------------------------------------------------------------------------------------*/

    /**
      Retourne le <CODE>rang</CODE> de l'<CODE>Op&eacute;ration</CODE> en cours.
    */
    public int getIndex()
    {
	return indexOfMe;
    }
     
    /*--------------------------------------------------------------------------------------*/

    /**
      Retourne la <CODE>T&acirc;che</CODE> <CODE>T</CODE> effectuant 
      l'<CODE>Op&eacute;ration</CODE> courante.
     */
    
    public Task getActiveTask()
    {
	return activeTask;
    }
    
    /*--------------------------------------------------------------------------------------*/

    /**
      Retourne la <CODE>T&acirc;che</CODE> <CODE>T'</CODE> partageant ce 
      <CODE>Buffer</CODE> avec <CODE>T</CODE>.
    */
    
    public Task getPassiveTask()
    {
	return passiveTask;
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Retourne l'<CODE>Op&eacute;ration</CODE> suivant celle de l'instance courante sur la 
       m&ecirc;me <CODE>T&acirc;che</CODE>, <CODE>null</CODE> si elle n'existe pas.
    */
    
    public Operation getNextFixedOperation()
    {
	if(this.getIndex()+1==activeTask.getNbOperations()) 
	    {
		return null;
	    }
	else
	    {
		return activeTask.getOperation(this.getIndex() + 1);
	    }
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Retourne l'<CODE>Op&eacute;ration</CODE> pr&eacute;c&eacute;dent celle de 
       l'instance courante sur la m&ecirc;me <CODE>T&acirc;che</CODE>, <CODE>null</CODE> si 
       elle n'existe pas.
    */
    
    public Operation getPreviousFixedOperation()
    {
	if (this.getIndex()==0)
	    {
		return null; 
	    }
	else
	    {
		return activeTask.getOperation(this.getIndex() - 1);
	    }
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Soit une <CODE>Op&eacute;ration</CODE> <CODE>B</CODE> li&eacute;e &agrave; celle de 
       l'instance courante <CODE>A</CODE> par une relation de <CODE>Buffer</CODE> 
       plein ou de <CODE>Buffer</CODE> vide telle que <CODE>B</CODE> doit 
       s'ex&eacute;cuter <U>apr&egrave;s</U> <CODE>A</CODE>; cette m&eacute;thode 
       retourne <CODE>B</CODE> si une telle <CODE>Op&eacute;ration</CODE> existe, 
       <CODE>null</CODE> sinon.      
    */
    
    public Operation getNextBufferedOperation()
    {
	return nextBufferedOperation;
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Soit une <CODE>Op&eacute;ration</CODE> <CODE>B</CODE> li&eacute;e &agrave; 
       celle de l'instance 
       courante <CODE>A</CODE> par une relation de <CODE>Buffer</CODE> plein ou de 
       <CODE>Buffer</CODE> vide telle que <CODE>B</CODE> doit s'ex&eacute;cuter 
       <U>avant</U> <CODE>A</CODE>; cette m&eacute;thode retourne <CODE>B</CODE> 
       si une telle <CODE>Op&eacute;ration</CODE> existe, <CODE>null</CODE> sinon.      
    */
    
    public Operation getPreviousBufferedOperation()
    {
	return previousBufferedOperation;
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Soit une <CODE>Op&eacute;ration</CODE> <CODE>B</CODE> li&eacute;e &agrave; celle de 
       l'instance courante <CODE>A</CODE> par une relation de <CODE>Buffer</CODE> 
       plein ou de <CODE>Buffer</CODE> vide telle que <CODE>B</CODE> doit 
       s'ex&eacute;cuter <U>avant</U> <CODE>A</CODE>; cette m&eacute;thode permet de 
       d&eacute;terminer cette contrainte en passant &agrave; l'<CODE>Op&eacute;ration</CODE> 
       courante son successeur <CODE>nextBufferedOperation</CODE>.<BR>Cette 
       m&eacute;thode se charge de doubler le cha&icirc;nage 
       (ou de v&eacute;rifier si il est effectivement double).
    */
    
    public void setNextBufferedOperation(Operation nextBufferedOperation)
    {
	if ((nextBufferedOperation == null)&&(this.nextBufferedOperation != null))
	    {
		Operation formerNextBufferedOperation = this.nextBufferedOperation;
		this.nextBufferedOperation = null;
		formerNextBufferedOperation.setPreviousBufferedOperation(null);
	    }
	else
	    {
		if (this.nextBufferedOperation != nextBufferedOperation)
		    {	
			this.setNextBufferedOperation(null);
			this.nextBufferedOperation = nextBufferedOperation;
			nextBufferedOperation.setPreviousBufferedOperation(this);
		    }
	    }
    }

    /*--------------------------------------------------------------------------------------*/

    /**
       Soit une <CODE>Op&eacute;ration</CODE> <CODE>B</CODE> li&eacute;e &agrave; celle de 
       l'instance courante <CODE>A</CODE> par une relation de <CODE>Buffer</CODE> 
       plein ou de <CODE>Buffer</CODE> vide telle que 
       <CODE>B</CODE> doit s'ex&eacute;cuter <U>apr&egrave;s</U> <CODE>A</CODE>; 
       cette m&eacute;thode permet de d&eacute;terminer cette contrainte en passant 
       &agrave l'<CODE>Op&eacute;ration</CODE> courante son pr&eacute;d&eacute;cesseur 
       <CODE>previousBufferedOperation</CODE>.<BR>
       Cette m&eacute;thode se charge de doubler le cha&icirc;nage 
       (ou de v&eacute;rifier si il est effectivement double).
    */
    
    public void setPreviousBufferedOperation(Operation previousBufferedOperation)
    {
	if ((previousBufferedOperation == null)&&(this.previousBufferedOperation != null))
	    {
		Operation formerPreviousBufferedOperation = this.previousBufferedOperation;
		this.previousBufferedOperation = null;
		formerPreviousBufferedOperation.setNextBufferedOperation(null);
	    }
	else
	    {
		if (this.previousBufferedOperation != previousBufferedOperation)	
		    {
			this.setPreviousBufferedOperation(null);
			this.previousBufferedOperation = previousBufferedOperation;
			previousBufferedOperation.setNextBufferedOperation(this);		
		    }
	    }
    }

    /*--------------------------------------------------------------------------------------*/

    /*
      Soit <CODE>I</CODE> l'indice de l'<CODE>Op&eacute;ration</CODE> <CODE>B</CODE> 
      li&eacute;e &agrave; celle de l'instance courante <CODE>A</CODE> par une relation de 
      famine ou d'interblocage telle que <CODE>B</CODE> doit s'ex&eacute;cuter 
      <U>apr&egrave;s</U> <CODE>A</CODE>. Cette m&eacute;thode retourne <CODE>True</CODE> 
      si cette contrainte est une contrainte de <CODE>DeadLock</CODE>, 
      <CODE>False</CODE> dans le cas contraire. <U>Attention</U> : Si <CODE>nextOperation</CODE> 
      est <CODE>null</CODE>, cette fonction jettera une <U>Exception</U>!
    
    
    public boolean isFullBufferConstraint()
    {
	return isFullBufferConstraint;
    }   
    */

    /*--------------------------------------------------------------------------------------*/

    /**
       Retourne le <CODE>Buffer</CODE> sur lequel cette <CODE>Op&eacute;ration</CODE> s'effectue.
    */
    
    public Buffer getBuffer()
    {
	return buffer;
    }   
    /*--------------------------------------------------------------------------------------*/

    /**
       Retourne l'image par <CODE>N</CODE> de cette op&eacute;ration.
    */
    
    public int getN()
    {
	return myImageByN;
    }   
    /*--------------------------------------------------------------------------------------*/

    /**
       Retourne cette <CODE>Op&eacute;ration</CODE> sous format 
       cha&icirc;ne de caract&egrave;res.
    */
    
    public String toString()
    {
	return new String(new Integer(buffer.getIndex()).toString());
    }   

}






Alexandre 2009-05-14