package buffalo.dataStructures;
import buffalo.dataStructures.*;
import buffalo.util.Fifo;
import java.util.Vector;
import buffalo.twoTasksAnalysis.TwoTasksCircuit;//déplacer la méthode sur les circuits...
/**
Ensemble de méthodes permettant de tracer des graphes
partiels (ou non) des contraintes de précédence
et d'y rechercher des circuits.
*/
public class TraceTracer
{
/*-------------------------------------------------------*/
/**
Trace les contraintes de Buffer vide de <CODE>myBuffer</CODE>,
retourne vrai si c'est possible, faux sinon.
*/
public static boolean traceEmptyBufferConstraints(Buffer myBuffer)
{
Task readingTask = myBuffer.getReadingTask();
Task writingTask = myBuffer.getWritingTask();
int nbReadingOperations = myBuffer.getNbInversedN(readingTask);
int nbWritingOperations = myBuffer.getNbInversedN(writingTask);
Operation readingOperation;
Operation writingOperation;
if (nbReadingOperations != nbWritingOperations)
{
return false;
}
for (int i = 0 ; i < nbReadingOperations ; i++)
{
writingOperation = myBuffer.getInversedN(i, writingTask);
readingOperation = myBuffer.getInversedN(i, readingTask);
writingOperation.setNextBufferedOperation(readingOperation);
}
return true;
}
/*-------------------------------------------------------*/
/**
Trace les contraintes de Buffer vide de tous les buffers,
retourne vrai si c'est possible, faux sinon.
*/
public static boolean traceAllEmptyBufferConstraints()
{
Buffer myBuffer;
int nbBuffers = Buffer.getNbBuffers();
boolean feasible;
for (int i = 0; i < nbBuffers ; i++)
{
myBuffer = Buffer.get(i);
feasible = traceEmptyBufferConstraints(myBuffer);
if (!feasible)
{
return false;
}
}
return true;
}
/*-------------------------------------------------------*/
/**
Trace les contraintes de Buffer plein de tous les buffers,
retourne vrai si c'est possible, faux sinon.
*/
public static boolean traceAllFullBufferConstraints()
{
Buffer myBuffer;
int nbBuffers = Buffer.getNbBuffers();
boolean feasible;
for (int i = 0; i < nbBuffers ; i++)
{
myBuffer = Buffer.get(i);
feasible = traceFullBufferConstraints(myBuffer);
if (!feasible)
{
return false;
}
}
return true;
}
/*-------------------------------------------------------*/
/**
Trace les contraintes de Buffer plein de <CODE>myBuffer</CODE>.
Cette méthode se charge
d'écraser le chaînage précédent.
Si par exemple on redimmensionne <CODE>myBuffer</CODE>,
cette méthode réajuste les arcs de la trace.
*/
public static boolean traceFullBufferConstraints(Buffer myBuffer)
{
Task readingTask = myBuffer.getReadingTask();
Task writingTask = myBuffer.getWritingTask();
int nbOperations = myBuffer.getNbInversedN(readingTask);
int sizeOfBuffer = myBuffer.getSize();
if (sizeOfBuffer <= 0) return false;
Operation readingOperation;
Operation writingOperation;
for (int i = 0 ; (i < sizeOfBuffer)&&(i < nbOperations) ; i ++)
{
writingOperation = myBuffer.getInversedN(i, writingTask);
writingOperation.setPreviousBufferedOperation(null);
}
for (int i = sizeOfBuffer ; (i < nbOperations - sizeOfBuffer + 1)&&(i < nbOperations); i++)
{
writingOperation = myBuffer.getInversedN(i, writingTask);
readingOperation = myBuffer.getInversedN(i - sizeOfBuffer,
readingTask);
writingOperation.setPreviousBufferedOperation(readingOperation);
}
int i;
if (nbOperations - sizeOfBuffer < -1)
{
i = 0;
}
else
{
i = nbOperations - sizeOfBuffer + 1;
}
for (; i < nbOperations ; i++)
{
readingOperation = myBuffer.getInversedN(i,
readingTask);
readingOperation.setNextBufferedOperation(null);
}
return true;
}
/*-------------------------------------------------------*/
/**
Elimine <U>tous</U> les arcs du graphe.
*/
public static void removeAllConstraints()
{
int nbBuffers = Buffer.getNbBuffers();
for (int i = 0; i < nbBuffers; i++)
{
removeAllConstraints(Buffer.get(i));
}
}
/*-------------------------------------------------------*/
/**
Elimine tous les arcs liés à des contraintes de
buffer vide ou de buffer plein du
buffer <CODE>myBuffer</CODE>.
*/
public static void removeAllConstraints(Buffer myBuffer)
{
int nbOperations = myBuffer.getNbInversedN(myBuffer.getReadingTask());
for (int i = 0; i < nbOperations; i++)
{
myBuffer.getInversedN(i, myBuffer.getReadingTask()).setNextBufferedOperation(null);
myBuffer.getInversedN(i, myBuffer.getReadingTask()).setPreviousBufferedOperation(null);
}
}
/*-------------------------------------------------------*/
/**
Recherche un circuit dans la trace d'exécution
<U>à deux Tâches</U> et le retourne.
Cette méthode retourne <CODE>null</CODE> si il n'y a pas de circuits.
*/
public static TwoTasksCircuit findTwoTasksCircuit(Task northTask,
Task southTask)
{
int upperBound = 2 * (northTask.getNbOperations() +
southTask.getNbOperations());
Fifo toVisit = new Fifo(upperBound);
toVisit.add(northTask.getOperation(0));
toVisit.add(southTask.getOperation(0));
Operation northSuspect = null;
Operation southSuspect = null;
Operation myOperation;
Operation nextOperation;
boolean[] northMarks = new boolean[northTask.getNbOperations()];
boolean[] southMarks = new boolean[southTask.getNbOperations()];
initialiseMarks(northMarks, southMarks);
while (toVisit.get() != null)
{
myOperation = (Operation)toVisit.get();
if (!isMarked(myOperation, northMarks, southMarks,
myOperation.getActiveTask() == northTask))
{
if (isMarquable(myOperation, northMarks, southMarks,
myOperation.getActiveTask() == northTask))
{
mark(myOperation, northMarks, southMarks,
myOperation.getActiveTask() == northTask);
nextOperation = myOperation.getNextFixedOperation();
if (nextOperation != null)
{
toVisit.add(nextOperation);
}
nextOperation = myOperation.getNextBufferedOperation();
if (nextOperation != null)
{
toVisit.add(nextOperation);
}
if (northSuspect == myOperation)
{
northSuspect = null;
}
if (southSuspect == myOperation)
{
southSuspect = null;
}
}
else
{
if (myOperation.getActiveTask()==northTask)
{
northSuspect = myOperation;
}
else
{
southSuspect = myOperation;
}
}
}
toVisit.extract();
}
if ((northSuspect != null)||(southSuspect != null))
{
return new TwoTasksCircuit
(northTask, northSuspect, southSuspect,
northSuspect.getPreviousBufferedOperation(),
southSuspect.getPreviousBufferedOperation());
}
else
{
return null;
}
}
/*-------------------------------------------------------*/
/*
Utilitaires sans intérêt
*/
private static void initialiseMarks(boolean[] northMarks,
boolean[] southMarks)
{
for (int i = 0 ; i < northMarks.length ; i++)
{
northMarks[i] = false;
}
for (int i = 0 ; i < southMarks.length ; i++)
{
southMarks[i] = false;
}
}
private static boolean isMarquable
(Operation myOperation,
boolean[] northMarks,
boolean[] southMarks,
boolean isNorthOperation)
{
return (
((isNorthOperation)&&
(
(myOperation.getIndex() == 0)||
(northMarks[myOperation.getIndex() - 1])
)&&
(
(myOperation.getPreviousBufferedOperation() == null)||
(southMarks
[myOperation.getPreviousBufferedOperation().getIndex()]
)
)
)
||
((!isNorthOperation)&&
(
(myOperation.getIndex() == 0)||
(southMarks[myOperation.getIndex() - 1])
)&&
(
(myOperation.getPreviousBufferedOperation() == null)||
(northMarks
[myOperation.getPreviousBufferedOperation().getIndex()]
)
)
)
);
}
private static void mark
(Operation myOperation,
boolean[] northMarks,
boolean[] southMarks,
boolean isNorthTask)
{
if (isNorthTask)
{
northMarks[myOperation.getIndex()] = true;
}
else
{
southMarks[myOperation.getIndex()] = true;
}
}
private static boolean isMarked
(Operation myOperation,
boolean[] northMarks,
boolean[] southMarks,
boolean isNorthTask)
{
return (
(isNorthTask) && (northMarks[myOperation.getIndex()])
||
(!isNorthTask) && (southMarks[myOperation.getIndex()])
);
}
/*-------------------------------------------------------*/
public static void main(String[] args)
{
try
{
Loader.run(args[0]);
}
catch(Loader.ScriptErrorException e)
{
System.out.println(e);
}
catch(Exception e)
{
System.out.println(e);
}
Buffer.get(0).setSize(1);
System.out.println(traceAllEmptyBufferConstraints() +
"\n--------------------------------");
System.out.println(findTwoTasksCircuit( Task.get(1),
Task.get(0)));
}
}