package buffalo.dataStructures;
import java.util.Vector;
/**
Composant stockant pour des <CODE>Tâches</CODE> des données
d'un poids variant d'un <CODE>Buffer</CODE> à l'autre.
Le but du jeu étant de déterminer la taille
à donner à ces <CODE>Buffers</CODE>!
<BR>
<BR>
Les attributs d'un <CODE>Buffer</CODE> sont :
<UL>
<LI>
Un <CODE>Poids</CODE> correspondant à la mémoire
occupée par le type de donnée élémentaire
écrit dans ce <CODE>Buffer</CODE>.
</LI>
<LI>
Une <CODE>Capacité</CODE> correspondant au nombre des données
élémentaires qu'il est possible d'écrire dans
ce <CODE>Buffer</CODE>.
</LI>
<LI>
Une <CODE>Tâche</CODE> notée <CODE>ReadingTask</CODE>,
chargée de lire dans ce <CODE>Buffer</CODE>.
</LI>
<LI>
Une <CODE>Tâche</CODE> notée <CODE>WritingTask</CODE>,
chargée d'écrire dans ce <CODE>Buffer</CODE>.
</LI>
</UL>
*/
public class Buffer
{
/*
La liste des instances de Buffer
*/
static Vector buffers;
/*
La taille définitive ou temporaire du Buffer. Cette taille sera
utilisée pour construire les chaînages.
*/
private int size=-1;
/*
Poids de l'information unitaire insérée dans le Buffer
*/
private int weight;
/*
l'indice de la tāche en ecriture sur ce buffer
*/
private Task writingTask;
/*
L'indice de la tāche en lecture sur ce buffer
*/
private Task readingTask;
/*
L'index de l'instance courante
*/
private int indexOfMe;
/*
Image inverse de N(o) pour les operations en lecture
*/
private Vector inverseImageOfNInRead;
/*
Image inverse de N(o) pour les operations en ecriture
*/
private Vector inverseImageOfNInWrite;
/*------------------------------------------------------------------------------*/
/*
Comme d'habitude, un constructeur privé, pour les bidouilles...
*/
private Buffer(int indexOfWritingTask, int indexOfReadingTask, int weight)
{
if (buffers==null)
{
buffers = new Vector();
}
this.weight = weight;
size=-1;
indexOfMe = buffers.size();
inverseImageOfNInRead = new Vector();
inverseImageOfNInWrite = new Vector();
}
/*------------------------------------------------------------------------------*/
/**
Crée un <CODE>Buffer</CODE>, dont l'écriture est
dédiée à la <CODE>Tâche</CODE> d'indice
<CODE>indexOfWritingTask</CODE> pour l'écriture et
à la <CODE>Tâche</CODE> d'indice <CODE>indexOfReadingTask</CODE>
pour la lecture. Le poids des données élémentaires
qui vont être écrites dans ce <CODE>Buffer</CODE> est
<CODE>weight</CODE>. Ce <CODE>Buffer</CODE> n'est renvoyé que si
les <CODE>Tâches</CODE> d'indices respectifs <CODE>indexOfWritingTask</CODE>
et <CODE>indexOfReadingTask</CODE> existent bel et bien!
*/
static Buffer createBuffer(int indexOfWritingTask, int indexOfReadingTask, int weight)
{
Buffer newBuffer = new Buffer(indexOfWritingTask, indexOfReadingTask, weight);
buffers.add(newBuffer);
newBuffer.connectWithTasks(indexOfWritingTask, indexOfReadingTask);
return newBuffer;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie l'indice de ce <CODE>Buffer</CODE>.
*/
public int getIndex()
{
return indexOfMe;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie la <CODE>Tâche</CODE> qui ecrit dans ce <CODE>Buffer</CODE>.
*/
public Task getWritingTask()
{
return writingTask;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie la <CODE>Tâche</CODE> qui lit dans ce <CODE>Buffer</CODE>.
*/
public Task getReadingTask()
{
return readingTask;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie le <CODE>Buffer</CODE> d'indice <CODE>indexOfBuffer</CODE>.
*/
public static Buffer get(int indexOfBuffer)
{
return (Buffer)(buffers.get((int)indexOfBuffer));
}
/*------------------------------------------------------------------------------*/
/**
Renvoie le nombre de <CODE>Buffers</CODE> crées.
*/
public static int getNbBuffers()
{
if (buffers!=null)
{
return buffers.size();
}
else
{
return 0;
}
}
/*------------------------------------------------------------------------------*/
/*
Connecte le Buffer courant aux deux Tâches passées en
paramètre.
*/
private void connectWithTasks(int indexOfWritingTask, int indexOfReadingTask)
{
writingTask = Task.get(indexOfWritingTask);
readingTask = Task.get(indexOfReadingTask);
Task.connectWithBuffer(indexOfWritingTask, indexOfReadingTask, indexOfMe);
}
/*------------------------------------------------------------------------------*/
/**
Renvoie la taille du <CODE>Buffer</CODE>, c'est-à-dire le nombre
de données élémentaires pouvant y être
écrites.
*/
public int getSize()
{
return size;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie le poids du <CODE>Buffer</CODE>, c'est-à-dire le poids des
données élémentaires qui y sont écrites.
*/
public int getWeight()
{
return weight;
}
/*------------------------------------------------------------------------------*/
/**
Modifie la taille du <CODE>Buffer</CODE>. <U>Attention :</U> le
chaînage des précédences dépendant des dimensions
des <CODE>Buffers</CODE> sera après cela obsolète! Toute
manipulation ultérieure ne pourra être pertinente que si ce
chaînage est recalculé!
*/
public void setSize(int newSizeOfBuffer)
{
this.size = newSizeOfBuffer;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie la <CODE>Tâche</CODE> partageant ce <CODE>Buffer</CODE>
avec la <CODE>Tâche</CODE> <CODE>T</CODE> d'indice
<CODE>indexOfTask</CODE> passé en paramètre. Cette
méthode renvoie -1 si <CODE>T</CODE> n'est pas connecté
à ce <CODE>Buffer</CODE>.
*/
public Task getOtherTask(int indexOfTask)
{
if (indexOfTask == readingTask.getIndex())
{
return writingTask;
}
if (indexOfTask == writingTask.getIndex())
{
return readingTask;
}
return null;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie au format chaîne de caractères le script de
création des <CODE>Buffers</CODE> et de connection de ces
derniers aux <CODE>Tâches</CODE>.
*/
public static String allToString()
{
String resultat = "#buffers \n";
int nbBuffers = getNbBuffers();
for( int i = 0; i < nbBuffers; i++)
{
resultat += get(i).toString() + " \n";
}
return resultat;
}
/*------------------------------------------------------------------------------*/
/**
Renvoie au format chaîne de caractères le script
de déclaration d'un <CODE>Buffer</CODE> et de connection
à deux <CODE>Tâches</CODE>.
*/
public String toString()
{
String resultat = (new Integer(getIndex())).toString() + "( ";
resultat += (new Integer(writingTask.getIndex())).toString() + ", ";
resultat += (new Integer(readingTask.getIndex())).toString() + ", ";
resultat += (new Integer(this.getWeight())).toString();
resultat += " )";
return resultat;
}
/*------------------------------------------------------------------------------*/
/*
Fonction permettant ultérieurement de manipuler l'image
inverse de N. Cette fonction ne vérifie pas le double
chaînage. C'est d'ailleurs pour cette raison qu'elle
n'est pas accessible en dehors du package.
*/
void addOperationToN(Operation operationToAdd, Task taskWhichDoIt)
{
if (taskWhichDoIt == readingTask)
{
inverseImageOfNInRead.add(operationToAdd);
}
if (taskWhichDoIt == writingTask)
{
inverseImageOfNInWrite.add(operationToAdd);
}
}
/*------------------------------------------------------------------------------*/
/**
Fonction renvoyant l'image de la réciproque de <CODE>N</CODE>;
comme une même valeur peut avoir plusieurs
antécédents, il convient pour éviter toute
ambiguité de préciser quelle <CODE>Tâche</CODE>
effectue cette <CODE>Opération</CODE>.
Cette fonction retourne "null" si N n'a pas d'image relative
aux paramètres passé. <BR>Pour de plus amples
renseignements, consulter la documentation d'Alix.
*/
public Operation getInversedN(int indexOfOperation, Task taskWhichDoIt)
{
if (taskWhichDoIt == readingTask)
{
return (Operation)inverseImageOfNInRead.get(indexOfOperation);
}
if (taskWhichDoIt == writingTask)
{
return (Operation)inverseImageOfNInWrite.get(indexOfOperation);
}
return null;
}
/*------------------------------------------------------------------------------*/
/**
Retourne le nombre d'<CODE>Opérations</CODE> effectuées
sur l'instance courante de <CODE>Buffer</CODE> par <CODE>task</CODE>,
<CODE>-1</CODE> si <CODE>task</CODE> n'est ni la <CODE>activeTask</CODE>
ni la <CODE>passiveTask</CODE>.
*/
public int getNbInversedN(Task task)
{
if (task == readingTask)
{
return inverseImageOfNInRead.size();
}
if (task == writingTask)
{
return inverseImageOfNInWrite.size();
}
return -1;
}
}