/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package jembench.stream; // TODOs: // Method names are currently quite ambiguous. Consider: // empty() -> isEmpty() // see also: java.util.Collection // full() -> isFull() // cnt() -> available() // or even size() as in Collection // free() -> capacity() // or even remainingCapacity() // // For increased familiarity with the J2SE API, also consider: // checkedEnq() -> offer() // deq() -> poll() // // MS: I don't care too much about those names. It's a very simple // class with very simple names. At least I know what is meant ;-) // // Do we really need the unchecked enq()? // If one knows what he/she is doing this is more efficient... /** * A non-blocking queue of byte buffer for single reader and single writer. * Classical usage is in an interrupt handler. * * @author Martin Schoeberl * */ public class BufferQueue { /** * The buffer, manipulated by the reader and writer. */ private final byte[][] data; /** * Read pointer, manipulated only by the reader. */ private volatile int rdPtr; /** * Write pointer, manipulated only by the writer. */ private volatile int wrPtr; /** * Create a buffer (queue of fixed size) * * @param array * of references. Has to contain one more element than the * intended buffer size. */ public BufferQueue(int capacity) { data = new byte[capacity + 1][]; rdPtr = wrPtr = 0; } /** * Is the buffer empty? * * @return true if empty */ public synchronized boolean empty() { return rdPtr == wrPtr; } /** * Is the buffer full? * * @return true if full */ public synchronized boolean full() { int i = wrPtr + 1; // >= makes Wolfgang's DFA happy if (i >= data.length) i = 0; return i == rdPtr; } /** * Unchecked enqueue of an element. Leaves the buffer corrupted when invoked * on a full buffer. * * @return */ public synchronized void enq(byte val[]) { int i = wrPtr; data[i++] = val; if (i >= data.length) i = 0; wrPtr = i; } /** * Dequeue of an element. Returns null for an empty queue. * * @return the value or null */ public synchronized byte[] deq() { if (rdPtr == wrPtr) return null; int i = rdPtr; byte[] val = data[i++]; if (i >= data.length) i = 0; rdPtr = i; return val; } /** * Buffer fill state * * @return available items */ public synchronized int cnt() { int i = wrPtr - rdPtr; if (i < 0) i += data.length; return i; } /** * Free elements in the buffer * * @return free slots */ public synchronized int free() { return data.length - 1 - cnt(); } /** * Write one entry * * @param val * the entry * @return true if successful */ public synchronized boolean checkedEnq(byte val[]) { if (full()) return false; enq(val); return true; } }