1 /*
2  * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.jmx.remote.internal;
27 
28 import java.util.AbstractList;
29 import java.util.Iterator;
30 
31 public class ArrayQueue<T> extends AbstractList<T> {
ArrayQueue(int capacity)32     public ArrayQueue(int capacity) {
33         this.capacity = capacity + 1;
34         this.queue = newArray(capacity + 1);
35         this.head = 0;
36         this.tail = 0;
37     }
38 
resize(int newcapacity)39     public void resize(int newcapacity) {
40         int size = size();
41         if (newcapacity < size)
42             throw new IndexOutOfBoundsException("Resizing would lose data");
43         newcapacity++;
44         if (newcapacity == this.capacity)
45             return;
46         T[] newqueue = newArray(newcapacity);
47         for (int i = 0; i < size; i++)
48             newqueue[i] = get(i);
49         this.capacity = newcapacity;
50         this.queue = newqueue;
51         this.head = 0;
52         this.tail = size;
53     }
54 
55     @SuppressWarnings("unchecked")
newArray(int size)56     private T[] newArray(int size) {
57         return (T[]) new Object[size];
58     }
59 
add(T o)60     public boolean add(T o) {
61         queue[tail] = o;
62         int newtail = (tail + 1) % capacity;
63         if (newtail == head)
64             throw new IndexOutOfBoundsException("Queue full");
65         tail = newtail;
66         return true; // we did add something
67     }
68 
remove(int i)69     public T remove(int i) {
70         if (i != 0)
71             throw new IllegalArgumentException("Can only remove head of queue");
72         if (head == tail)
73             throw new IndexOutOfBoundsException("Queue empty");
74         T removed = queue[head];
75         queue[head] = null;
76         head = (head + 1) % capacity;
77         return removed;
78     }
79 
get(int i)80     public T get(int i) {
81         int size = size();
82         if (i < 0 || i >= size) {
83             final String msg = "Index " + i + ", queue size " + size;
84             throw new IndexOutOfBoundsException(msg);
85         }
86         int index = (head + i) % capacity;
87         return queue[index];
88     }
89 
size()90     public int size() {
91         // Can't use % here because it's not mod: -3 % 2 is -1, not +1.
92         int diff = tail - head;
93         if (diff < 0)
94             diff += capacity;
95         return diff;
96     }
97 
98     private int capacity;
99     private T[] queue;
100     private int head;
101     private int tail;
102 }
103