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; } }