blob: ebe0915173d7ca742e85863d7e0717d5a7687ee9 [file] [log] [blame]
/* Copyright (c) 2001-2010, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.lib;
import java.util.NoSuchElementException;
// fredt@users 20020130 - patch 1.7.0 by fredt - new class
/**
* jdk 1.1 compatible minimal implementation of a list object suitable for
* stack, queue and deque usage patterns backed by an Object[].
* The memory footprint of the HsqlDeque doubles when it gets full
* but does not shrink when it gets empty.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 1.9.0
* @since 1.7.0
*/
public class HsqlDeque extends BaseList implements HsqlList {
private Object[] list;
private int firstindex = 0; // index of first list element
private int endindex = 0; // index of last list element + 1
// can grow to fill list
// if elementCount == 0 then firstindex == endindex
private static final int DEFAULT_INITIAL_CAPACITY = 10;
public HsqlDeque() {
list = new Object[DEFAULT_INITIAL_CAPACITY];
}
public int size() {
return elementCount;
}
public boolean isEmpty() {
return elementCount == 0;
}
public Object getFirst() throws NoSuchElementException {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return list[firstindex];
}
public Object getLast() throws NoSuchElementException {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return list[endindex - 1];
}
public Object get(int i) throws IndexOutOfBoundsException {
int index = getInternalIndex(i);
return list[index];
}
public void add(int i, Object o) throws IndexOutOfBoundsException {
throw new java.lang.RuntimeException();
}
public Object set(int i, Object o) throws IndexOutOfBoundsException {
int index = getInternalIndex(i);
Object result = list[index];
list[index] = o;
return result;
}
public Object removeFirst() throws NoSuchElementException {
if (elementCount == 0) {
throw new NoSuchElementException();
}
Object o = list[firstindex];
list[firstindex] = null;
firstindex++;
elementCount--;
if (elementCount == 0) {
firstindex = endindex = 0;
} else if (firstindex == list.length) {
firstindex = 0;
}
return o;
}
public Object removeLast() throws NoSuchElementException {
if (elementCount == 0) {
throw new NoSuchElementException();
}
endindex--;
Object o = list[endindex];
list[endindex] = null;
elementCount--;
if (elementCount == 0) {
firstindex = endindex = 0;
} else if (endindex == 0) {
endindex = list.length;
}
return o;
}
/*
public Object remove(int i){
return get(i);
}
public void add(int i, Object o) {
}
*/
public boolean add(Object o) {
resetCapacity();
if (endindex == list.length) {
endindex = 0;
}
list[endindex] = o;
elementCount++;
endindex++;
return true;
}
public boolean addLast(Object o) {
return add(o);
}
public boolean addFirst(Object o) {
resetCapacity();
firstindex--;
if (firstindex < 0) {
firstindex = list.length - 1;
if (endindex == 0) {
endindex = list.length;
}
}
list[firstindex] = o;
elementCount++;
return true;
}
public void clear() {
if (elementCount == 0) {
return;
}
firstindex = endindex = elementCount = 0;
for (int i = 0; i < list.length; i++) {
list[i] = null;
}
}
public int indexOf(Object value) {
for (int i = 0; i < elementCount; i++) {
int index = firstindex + i;
if (index >= list.length) {
index -= list.length;
}
if (list[index] == value) {
return i;
}
if (value != null && value.equals(list[index])) {
return i;
}
}
return -1;
}
public Object remove(int index) {
int target = getInternalIndex(index);
Object value = list[target];
if (target == firstindex) {
list[firstindex] = null;
firstindex++;
if (firstindex == list.length) {
firstindex = 0;
}
} else if (target > firstindex) {
System.arraycopy(list, firstindex, list, firstindex + 1,
target - firstindex);
list[firstindex] = null;
firstindex++;
if (firstindex == list.length) {
firstindex = 0;
}
} else {
System.arraycopy(list, target + 1, list, target,
endindex - target - 1);
endindex--;
list[endindex] = null;
if (endindex == 0) {
endindex = list.length;
}
}
elementCount--;
if (elementCount == 0) {
firstindex = endindex = 0;
}
return value;
}
private int getInternalIndex(int i) throws IndexOutOfBoundsException {
if (i < 0 || i >= elementCount) {
throw new IndexOutOfBoundsException();
}
int index = firstindex + i;
if (index >= list.length) {
index -= list.length;
}
return index;
}
private void resetCapacity() {
if (elementCount < list.length) {
return;
}
Object[] newList = new Object[list.length * 2];
System.arraycopy(list, firstindex, newList, firstindex,
list.length - firstindex);
if (endindex <= firstindex) {
System.arraycopy(list, 0, newList, list.length, endindex);
endindex = list.length + endindex;
}
list = newList;
}
public void toArray(Object[] array) {
int tempCount = list.length - firstindex;
if (tempCount > elementCount) {
tempCount = elementCount;
}
System.arraycopy(list, firstindex, array, 0, tempCount);
if (endindex <= firstindex) {
System.arraycopy(list, 0, array, tempCount, endindex);
endindex = list.length + endindex;
}
}
}