Quadcap Embeddable Database

com/quadcap/util/collections/ArrayQueue.java

Go to the documentation of this file.
00001 package com.quadcap.util.collections; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 /** 00042 * Implements the Queue interface using a growable array. 00043 * 00044 * @author Stan Bailes 00045 */ 00046 public class ArrayQueue implements Queue { 00047 int head = 0; 00048 int tail = 0; 00049 int capacity = 0; 00050 Object[] queue = null; 00051 00052 /** 00053 * Create an empty Array queue with unbounded capacity 00054 */ 00055 public ArrayQueue() { 00056 this(0, -1); 00057 } 00058 00059 /** 00060 * Create an empty queue with an initial capacity 00061 */ 00062 public ArrayQueue(int capacity) { 00063 this(0, capacity); 00064 } 00065 00066 /** 00067 * Create an ArrayQueue with an initial capacity. 00068 */ 00069 public ArrayQueue(int initialSize, int capacity) { 00070 this.capacity = capacity; 00071 this.queue = new Object[initialSize + 1]; 00072 } 00073 00074 /** 00075 * Specify the maximum capacity of this queue, -1 means unbounded. 00076 * 00077 * @param capacity the new capacity of the queue, or -1 to specify a 00078 * queue of unlimited size. 00079 */ 00080 public final void setCapacity(int capacity) { 00081 if (capacity < size()) { 00082 throw new RuntimeException("can't set capacity less than size"); 00083 } 00084 if (capacity < queue.length) { 00085 resize(size() + 1); 00086 } 00087 this.capacity = capacity; 00088 } 00089 00090 /** 00091 * Return the number of items in the queue. 00092 * @return the queue's size 00093 */ 00094 public final int size() { 00095 int ret = 0; 00096 if (head > tail) { 00097 ret = head - tail; 00098 } else if (head < tail) { 00099 ret = queue.length - tail + head; 00100 } 00101 return ret; 00102 } 00103 00104 /** 00105 * Add an object to the front of the queue. 00106 * 00107 * @param obj the object to add 00108 */ 00109 public final void pushFront(Object obj) { 00110 addFront(obj); 00111 } 00112 00113 public final void addFront(Object obj) { 00114 checkSizeForAdd(); 00115 queue[head++] = obj; 00116 if (head == queue.length) head = 0; 00117 } 00118 00119 /** 00120 * Add an object to the back of the queue. 00121 * @param obj the object to add 00122 */ 00123 public final void pushBack(Object obj) { 00124 addBack(obj); 00125 } 00126 00127 public final void addBack(Object obj) { 00128 checkSizeForAdd(); 00129 if (--tail < 0) tail = queue.length - 1; 00130 queue[tail] = obj; 00131 } 00132 00133 /** 00134 * Access the object at the front of the queue. Return null 00135 * if the queue is empty. 00136 * 00137 * @return the item at the head of the queue 00138 */ 00139 public final Object head() { 00140 Object ret = null; 00141 if (size() > 0) { 00142 ret = queue[head > 0 ? head - 1 : queue.length - 1]; 00143 } 00144 return ret; 00145 } 00146 00147 /** 00148 * Access the object at the back of the queue. Return null 00149 * if the queue is empty. 00150 * 00151 * @return the item at the tail of the queue 00152 */ 00153 public final Object tail() { 00154 Object ret = null; 00155 if (size() > 0) { 00156 ret = queue[tail]; 00157 } 00158 return ret; 00159 } 00160 00161 /** 00162 * Remove and return the item at the front of the queue. Return null 00163 * if the queue is empty. 00164 * 00165 * @return the item at the head of the queue 00166 */ 00167 public final Object popFront() { 00168 Object ret = null; 00169 if (size() > 0) { 00170 head = head > 0 ? head - 1 : queue.length - 1; 00171 ret = queue[head]; 00172 } 00173 return ret; 00174 } 00175 00176 /** 00177 * Remove and return the item at the back of the queue. Return null 00178 * if the queue is empty. 00179 * 00180 * @return the item at the tail of the queue 00181 */ 00182 public final Object popBack() { 00183 Object ret = null; 00184 if (size() > 0) { 00185 ret = queue[tail++]; 00186 if (tail >= queue.length) tail = 0; 00187 } 00188 return ret; 00189 } 00190 00191 public final void push(Object obj) { 00192 addBack(obj); 00193 } 00194 00195 public final Object pop() { 00196 return popBack(); 00197 } 00198 00199 public final Object top() { 00200 return tail(); 00201 } 00202 00203 public final Object top(int pos) { 00204 Object ret = null; 00205 if (pos >= 0 && pos < size()) { 00206 int x = tail + pos; 00207 if (x >= queue.length) x -= queue.length; 00208 ret = queue[x]; 00209 } 00210 return ret; 00211 } 00212 00213 /** 00214 * Remove the specified object 00215 */ 00216 public final void remove(Object obj) { 00217 int pos = head - 1; 00218 int cnt = size(); 00219 int last = -1; 00220 for (int i = 0; i < cnt; i++) { 00221 if (pos < 0) pos = queue.length - 1; 00222 if (last < 0) { 00223 if (queue[pos] == obj) { 00224 last = pos; 00225 } 00226 } else { 00227 queue[last] = queue[pos]; 00228 tail = last; 00229 last = pos; 00230 } 00231 } 00232 } 00233 00234 final void checkSizeForAdd() { 00235 int siz = size(); 00236 if (siz == queue.length - 1) { 00237 if (capacity <= 0) { 00238 resize(queue.length + queue.length/8 + 1); 00239 } else { 00240 if (siz >= capacity) { 00241 throw new RuntimeException("queue full"); 00242 } 00243 resize(Math.min(capacity+1, 00244 queue.length + queue.length/8 + 1)); 00245 } 00246 } 00247 } 00248 00249 final void resize(int newsize) { 00250 Object[] nq = new Object[newsize]; 00251 if (head > tail) { 00252 System.arraycopy(queue, tail, nq, 0, head - tail); 00253 head -= tail; 00254 tail = 0; 00255 } else if (head < tail) { 00256 System.arraycopy(queue, tail, nq, 0, queue.length - tail); 00257 if (head > 0) { 00258 System.arraycopy(queue, 0, nq, queue.length - tail, head); 00259 } 00260 head += queue.length - tail; 00261 tail = 0; 00262 } else { 00263 // queue's empty 00264 head = tail = 0; 00265 } 00266 queue = nq; 00267 } 00268 00269 public String toString() { 00270 StringBuffer sb = new StringBuffer("ArrayQueue"); 00271 sb.append('['); 00272 int pos = head - 1; 00273 int cnt = size(); 00274 for (int i = 0; i < cnt; i++) { 00275 if (pos < 0) pos = queue.length - 1; 00276 if (i > 0) sb.append(','); 00277 sb.append(queue[pos--]).toString(); 00278 } 00279 sb.append(']'); 00280 return sb.toString(); 00281 } 00282 }