package com.cooliris.media;
public final class Deque<E extends Object> {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private E[] mArray;
private int mHead = 0;
private int mTail = 0;
@SuppressWarnings("unchecked")
public Deque() {
mArray = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
@SuppressWarnings("unchecked")
public Deque(int initialCapacity) {
// CR: check initialCapacity & (initialCapacity - 1) == 0.
mArray = (E[]) new Object[initialCapacity];
}
public boolean isEmpty() {
return mHead == mTail;
}
public int size() {
return (mTail - mHead) & (mArray.length - 1); // CR: wtf?!? this
// definitely needs a
// comment.
}
public void clear() {
E[] array = mArray;
int head = mHead;
int tail = mTail;
if (head != tail) {
int mask = array.length - 1;
do {
array[head] = null;
head = (head + 1) & mask;
} while (head != tail);
mHead = 0;
mTail = 0;
}
}
public E get(int index) {
E[] array = mArray;
if (index >= size()) {
throw new IndexOutOfBoundsException();
}
return array[(mHead + index) & (array.length - 1)];
}
public void addFirst(E e) {
E[] array = mArray;
int head = (mHead - 1) & (array.length - 1);
mHead = head;
array[head] = e;
if (head == mTail) {
expand();
}
}
public void addLast(E e) {
E[] array = mArray;
int tail = mTail;
array[tail] = e;
tail = (tail + 1) & (array.length - 1);
mTail = tail;
if (mHead == tail) {
expand();
}
}
public E pollFirst() {
E[] array = mArray;
int head = mHead;
E result = array[head];
if (result == null) {
return null;
}
array[head] = null;
mHead = (head + 1) & (array.length - 1);
return result;
}
public E pollLast() {
E[] array = mArray;
int tail = (mTail - 1) & (array.length - 1);
E result = array[tail];
if (result == null) {
return null;
}
array[tail] = null;
mTail = tail;
return result;
}
@SuppressWarnings("unchecked")
private void expand() {
// Must be called only when head == tail.
E[] array = mArray;
int head = mHead;
int capacity = array.length;
int rightSize = capacity - head;
int newCapacity = capacity << 1;
Object[] newArray = new Object[newCapacity];
System.arraycopy(array, head, newArray, 0, rightSize);
System.arraycopy(array, 0, newArray, rightSize, head);
mArray = (E[]) newArray;
mHead = 0;
mTail = capacity;
}
}