/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package com.sun.enterprise.web.connector.grizzly; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; /** * A circular queue that may potentially grow if needed. * * @param E type of objects to queue * @author Charlie Hunt */ public class CircularQueue { /** * initial default capacity of this circular queue */ final static private int DEFAULT_CAPACITY = 2; /** * queue capacity */ private int capacity; /** * index to head of the queue */ private int head = 0; /** * index to tail of the queue */ private int tail = 0; /** * current queue depth / size */ private int queueSize = 0; /** * queue of s */ private Object[] queue; /** * Creates a circular queue of default size */ public CircularQueue() { this(DEFAULT_CAPACITY); } /** * Creates a circular queue of capacity size * * @param capacity initial capacity of this queue */ @SuppressWarnings("unchecked") public CircularQueue(int capacity) { this.capacity = capacity; this.head = 0; this.tail = 0; this.queueSize = 0; this.queue = new Object[this.capacity]; } /** * Removes a from the head of the queue * * @return a at the head of the queue */ @SuppressWarnings("unchecked") public E poll() { if (!empty()) { queueSize--; head = (head + 1) % capacity; E e = (E)queue[head]; queue[head] = null; return e; } else { return null; } } /** * Adds a to the queue * * @param e to add to the queue */ public void addLast(E e) { if (full()) { doubleCapacity(); } queueSize++; tail = (tail + 1) % capacity; queue[tail] = e; } /** * double capacity of this queue */ @SuppressWarnings("unchecked") private void doubleCapacity() { int newSize = capacity * 2; E[] newCircularQueue = (E[]) new Object[newSize]; // copy old old queue into new queue int i = 1; while (!empty()) { newCircularQueue[i++] = poll(); } // update head and tail this.head = 0; this.queueSize = this.tail = (i-1); this.capacity = newSize; this.queue = newCircularQueue; } /** * returns the number of s in the queue * * @return number of s in the queue */ public int size() { return queueSize; } /** * is queue empty ? * * @return true if queue is empty, otherwise false */ public boolean empty() { return queueSize == 0; } /** * is queue full ? * * @return true if queue is full, otherwise false */ public boolean full() { return queueSize == capacity; } private void printQueue() { System.out.print("Size: " + queueSize + ", tail: " + tail + ", head: " + head + ", queue: "); for (int i = 0; i < capacity; i++) System.out.print("q[" + i + "]=" + queue[i] + "; "); System.out.println(); } /* ------------------ for unit testing ------------------- */ private static char getNextChar(Reader in) { char ch = '\0'; try { ch = (char)in.read(); } catch (IOException ex) { ex.printStackTrace(); } return ch; } public static void main(String[] args) { Reader in = new InputStreamReader(System.in); CircularQueue queue = new CircularQueue(4); char ch; while ((ch = getNextChar(in)) != 'q') { switch (ch) { case 'i': ch = getNextChar(in); queue.addLast(ch); System.out.println(ch + " inserted"); break; case 'd': System.out.println(queue.poll() + " removed"); break; case 'p': queue.printQueue(); break; default: System.out.println("Input error"); } while (getNextChar(in) != '\n') {} } } }