//-< ArrayOfLong.java >----------------------------------------------*--------* // GOODS Version 2.02 (c) 1998 GARRET * ? * // (Generic Object Oriented Database System) * /\| * // GOODS Persistent Class Library * / \ * // Created: 1-Oct-98 K.A. Knizhnik * / [] \ * // Last update: 18-Oct-98 K.A. Knizhnik * GARRET * //-------------------------------------------------------------------*--------* // Dynamic array of longs //-------------------------------------------------------------------*--------* package goodslib; import goodsjpi.*; /** * ArrayOfLong is just that, an array of longs. It is fully * persistent, as it it's derived from Persistent. All reads cause a fetch of the * data, all writes mark it dirty and to be saved. * * @author K.A. Knizhnik * @version 1.0 */ public class ArrayOfLong extends AnyArray { /** * array holds the longs in an [] */ protected long[] array; /** * Creates a new ArrayOfLong instance. * * @param size is the initial size, (length) */ public ArrayOfLong(int size) { this(size, size == 0 ? 16 : size); } /** * Creates a new ArrayOfLong instance. (Full of false) * * @param size , or length of the array * @param allocatedSize is the size it can grow to without re-sizing */ public ArrayOfLong(int size, int allocatedSize) { Assert.that(size <= allocatedSize); array = new long[allocatedSize]; used = size; } /** * Creates a new ArrayOfLong instance, as a copy of the given * long[] * * @param src a long[] that will be copied */ public ArrayOfLong(long[] src) { int length = src.length; array = new long[length]; used = length; System.arraycopy(src, 0, array, 0, length); } /** * Put a long value at a given index * * @param index an int value, where the value should be set * @param value the long value to be set */ public synchronized void putAt(int index, long value) { if (index < 0 || index >= used) { throw new ArrayIndexOutOfBoundsException(index); } Metaobject.modify(); array[index] = value; } /** * Get a long at the specified index * * @param index of the long you want * @return a long value, at index "index" */ public synchronized long getAt(int index) { if (index < 0 || index >= used) { throw new ArrayIndexOutOfBoundsException(index); } return array[index]; } /** * Resize the amount of space taken by the array. Either grow or shrink as * necessary. You get an IndexOutOfBoundException for negative values.
* of course the old data is copied. * * @param newSize an int denoting the new size. */ public synchronized void changeSize(int newSize) { if (newSize < 0) { throw new ArrayIndexOutOfBoundsException(newSize); } int allocated = array.length; if (newSize > allocated) { allocated = (allocated*2 > newSize) ? allocated*2 : newSize; long[] newArray = new long[allocated]; System.arraycopy(array, 0, newArray, 0, used); array = newArray; } else if (newSize < used) { for (int i = used; --i >= newSize; array[i] = 0); } used = newSize; } /** * insert a "count" amount of values at a given index. Throws an * IndexOutOfBoundsException for too small (<0) or too big (>length) count or index. * * @param index , where to start inserting value(s) * @param count , how many values to insert * @param value a long value to insert */ public synchronized void insert(int index, int count, long value) { if (count < 0) { throw new ArrayIndexOutOfBoundsException(count); } else if (index < 0 || index > used) { throw new ArrayIndexOutOfBoundsException(index); } changeSize(used+count); System.arraycopy(array, index, array, index+count, used-index-count); while (--count >= 0) { array[index++] = value; } } /** * remove a number of values. The array shrinks in it's length, but no * resizing is done. Get an IndexOutOfBoundsException for inappropriate index or * count values. * * @param index , where to start removing * @param count , how many values to remove */ public synchronized void remove(int index, int count) { if (count < 0) { throw new ArrayIndexOutOfBoundsException(count); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(index); } else if (index+count > used) { throw new ArrayIndexOutOfBoundsException(index+count); } System.arraycopy(array, index+count, array, index, used-count-index); changeSize(used-count); } /** * Use the array as a stack with the push method. * * @param value , a long to push to the stack */ public synchronized void push(long value) { changeSize(used+1); array[used-1] = value; } /** * Use the array as a stack and pop a value. (Value is removed) * IndexOutOfBoundsExceptions comes when array has hit 0 length. * * @return the top most long value */ public synchronized long pop() { if (used == 0) { throw new ArrayIndexOutOfBoundsException(0); } long value = array[--used]; array[used] = 0; return value; } /** * Check the top boolean with the top method. This returns what * pop returns, just it doesn't remove the value. In other stack * implementations it may be called peek() * * @return a long value */ public synchronized long top() { if (used == 0) { throw new ArrayIndexOutOfBoundsException(0); } return array[used-1]; } /** * append add the given values to the end of the array * * @param tail a long[] that will be appended */ public synchronized void append(long[] tail) { int size = used; changeSize(size + tail.length); System.arraycopy(tail, 0, array, size, tail.length); } /** * toArray converts the internal representation to a long[] , of * correct size. Ie: the .length of the return == this.size() * * @return a long[] value */ public synchronized long[] toArray() { long[] arr = new long[used]; System.arraycopy(array, 0, arr, 0, used); return arr; } /** * copy into this array from a destination, a given amount of values. * Get a IndexOutOfBounds if the src or count don't fit * * @param dstIndex , the index (of this array) where to copy to * @param src a long[] , where to copy from * @param srcIndex an int , where to start copying from * @param count an int , how many values to copy */ public synchronized void copy(int dstIndex, long[] src, int srcIndex, int count) { if (dstIndex < 0) { throw new ArrayIndexOutOfBoundsException(dstIndex); } else if (dstIndex+count > used) { throw new ArrayIndexOutOfBoundsException(dstIndex+count); } Metaobject.modify(); System.arraycopy(src, srcIndex, array, dstIndex, count); } /** * indexOf returns the first occurrence of val * * @param val a long to be looked for * @return an int, where the value was found, or -1 */ public synchronized int indexOf(long val) { for (int i = 0; i < used; i++) { if (array[i] == val) { return i; } } return -1; } /** * Find the lastIndexOf a given value * * @param val a long value to be found (from the back) * @return an int , where the value was found, or -1 */ public synchronized int lastIndexOf(long val) { for (int i = used; --i >= 0;) { if (array[i] == val) { return i; } } return -1; } }