/** FILE: buffermy.java **/

package BUFFER;


// Referenced classes of package BUFFER:
//            buffer, accex, sala

/*
 * Gestione Personalizzata con tolleranza...
 *
 * la get è in assenza di politica,
 * la put si comporta anarchicamente fino a quando il processo che è in testa alla lista non ha 
 * aspettato per tolleranza eventi. Allora tutti i nuovi processi si mettono in coda fino a quando
 * il primo non è passato. Se il primo elemento non è in situazione critica possono i processi nella
 * lista possono uscire liberamente.
 */

public class buffermy extends buffer
{

    public buffermy(int i)
    {
        getcorrente = 1;
        getinfila = 1;
        blocco = false;
        testa = new sala();
        coda = testa;
        tolleranza = i;
    }

    public synchronized void put(String s)
        throws InterruptedException
    {
        accex accex1 = accput;   // nuovo oggetto assegnato al thread per memorizzare gli accessi
        accex1.next = new accex();
        accex1.acc1 = accessi++;    // QUI incremento accessi == gli EVENTI
        accput = accput.next;
        sala sala1 = null;  

        // attendi fino a quando entri nel buffer oppure se è attuato il blocco e non sei in testa alla lista,

        while (liberi < s.length() || blocco && testa != sala1)
        {
            if(sala1 == null)
            {
                sala1 = coda;  // nuovo oggetto assegnato al thread per la lista di attesa
                coda.next = new sala();
                coda = coda.next;
                sala1.evento = accessi - 1;
                coda.pred = sala1;
            }
            wait();
        }

        if(sala1 != null)  // se è passato un processo che era il lista
            if(testa == sala1)  // se è il processo in testa
            {
                testa = testa.next;  // taglia in testa
                testa.pred = null;
            }
            else
            if(coda == sala1) // se è passato un processo che era in coda alla lista
            {
                coda = coda.pred; // taglia in coda
                coda.next = null;
            }
            else  // se è passato un processo che è in mezzo alla lista
            {
                sala1.pred.next = sala1.next;  // taglia al centro
                sala1.next.pred = sala1.pred;
            }
        if(accessi - testa.evento > tolleranza) // controllo se in testa c'è un processo che ha atteso troppo
            blocco = true;  // politica in corso
        else
            blocco = false; // ritorno a politica pseudo-anarchica
        accex1.acc2 = accessi;
        notifyAll();
        super.put(s); // scrittura sul buffer --> vedi buffer.java
    }

    public synchronized String get()
        throws InterruptedException
    {
        accex accex1 = accget;   // nuovo oggetto assegnato al thread per memorizzare gli accessi
        accex1.next = new accex();
        accex1.acc1 = accessi++;    // QUI incremento accessi == gli EVENTI
        accget = accget.next;
        while(liberi == 200) wait();
        accex1.acc2 = accessi;
        if(accessi - testa.evento > tolleranza)
            blocco = true;
        else
            blocco = false;
        notifyAll();
        return super.get();
    }

    int getcorrente;
    int getinfila;
    boolean blocco;
    sala testa;
    sala coda;
    private int tolleranza;
}