/* * @(#)CircularBuffer.java 1.8 02/08/21 * * Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved. */ package com.sun.media; import javax.media.Buffer; /** * CircularQueue * It implements a circular FIFO queue of references to Objects. */ public class CircularBuffer { /** buffer to hold the references. Would be changed to buffer array, when Buffer stabalize **/ private Buffer buf[]; /** write pointer **/ private int head ; /** read pointer **/ private int tail ; /** number of frames that can be read **/ private int availableFramesForReading ; /** number of frames that can be written **/ private int availableFramesForWriting ; /** number of frames that were checked out for reading **/ private int lockedFramesForReading ; /** number of frames that were checked out for writing **/ private int lockedFramesForWriting ; /** size of the FIFO queue **/ private int size; /** create a queue with max number of elements * @param n the max number of elements **/ public CircularBuffer(int n) { size = n; buf = new Buffer[n]; for (int i = 0;i < n;i++) buf[i] = new ExtBuffer(); // *** generalize this reset(); } /** indicates that the latest read frame is no longer in use **/ public synchronized void readReport() { if (lockedFramesForReading == 0) error(); lockedFramesForReading--; availableFramesForWriting++; } /** returns <code>true</code> if read() would succeed **/ public synchronized boolean canRead(){ return (availableFramesForReading > 0); } public synchronized boolean lockedRead() { return (lockedFramesForReading > 0); } public synchronized boolean lockedWrite() { return (lockedFramesForWriting > 0); } /** * Gets frame with valid buffer from the queue **/ public synchronized Buffer read() { if (availableFramesForReading == 0) error(); Buffer buffer = buf[head]; lockedFramesForReading++; availableFramesForReading--; head++; if (head >= size) head -= size; return buffer; } /** * Gets frame with valid buffer from the queue **/ public synchronized Buffer peek() { if (availableFramesForReading == 0) error(); return buf[head]; } /** indicates that latest Object returns to the queue * <i><br>we removed writeReport(false), since we have the mechanism in javax.media.Buffer (discard).</i> **/ public synchronized void writeReport() { if (lockedFramesForWriting == 0) error(); lockedFramesForWriting--; availableFramesForReading++; // wrote data OK /* @@@ buffer invalid: removed since we have the mechanism in javax.media.Buffer { availableFramesForWriting++; // buffer not written tail--; if (tail<0) tail += size; } */ } /** returns empty buffer object to put data in **/ public synchronized Buffer getEmptyBuffer() { if (availableFramesForWriting == 0) error(); lockedFramesForWriting++; Buffer buffer = buf[tail]; availableFramesForWriting--; tail++; if (tail >= size) tail -= size; return buffer; } /** returns <code>true</code> if getEmptyObject() would succeed **/ public synchronized boolean canWrite(){ return (availableFramesForWriting>0); } /** error dump **/ public void error() { throw new RuntimeException ("CircularQueue failure:\n head="+head+"\n tail="+tail+ "\n canRead="+availableFramesForReading+"\n canWrite="+availableFramesForWriting+ "\n lockedRead="+lockedFramesForReading+"\n lockedWrite="+lockedFramesForWriting); } public void print() { System.err.println("CircularQueue : head="+head+" tail="+tail+ " canRead="+availableFramesForReading+" canWrite="+availableFramesForWriting+ " lockedRead="+lockedFramesForReading+" lockedWrite="+lockedFramesForWriting); } /** reset the queue **/ public synchronized void reset(){ availableFramesForReading = 0; availableFramesForWriting = size; lockedFramesForReading = 0; lockedFramesForWriting = 0; head = 0; tail = 0; } }