/**
 * A buffer contains up to SIZE elements.
 *
 * @version     1.1    February 7, 2000
 * @author      Franck van Breugel
 */
public class Buffer 
{
    private static final int SIZE = 10;  // size of this buffer

    private Object[] buffer;             // contains elements of this buffer
    private int inCount;                 // number of elements put in this buffer
    private int outCount;                // number of elements got out of this buffer
    private boolean done;                // are all producers done?

    /**
     * Creates a buffer.
     */
    public Buffer()
    {
        buffer = new Object[SIZE];
        inCount = 0;
        outCount = 0;
        done = false;
    }

    /** 
     * Removes the first element from this buffer and returns it.
     *
     * @return Element removed from this buffer.
     */
    public synchronized Object get() throws InterruptedException
    {
        while (outCount >= inCount) 
        {
            if (done)
	    {
		Consumer.CONSUMERS.interrupt();
            }
            else
	    {
                wait();
            }
        }
        Object temp = buffer[outCount % SIZE];
        outCount++;
        notifyAll();
        return temp;
    }

    /** 
     * Puts the specified element in at the end of this buffer.
     *
     * @param element Element to be added to this buffer.
     */
    public synchronized void put(Object element) throws InterruptedException
    {
        while (inCount - outCount >= SIZE) 
        {
            wait();
        }
        buffer[inCount % SIZE] = element;
        inCount++;
        notifyAll();
    }

    /**
     * Sets done to true.  If the buffer is empty, then stop all consumers.
     */
    public synchronized void setDone()
    {
        done = true;
        if (outCount >= inCount)
	{
            Consumer.CONSUMERS.interrupt();
        }
    }
}





