/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.util;
import java.util.logging.Logger;
/**
* Growable array of float tuples.
*/
public class FloatTupleArrayImpl implements FloatTupleArray {
private static Logger log = Logger.getLogger(FloatTupleArrayImpl.class.getName());
/** Factor by which the arrays are grown when they run out of space. */
public static final float DEF_GROW_FACTOR = 1.5f;
protected float[][] elements;
private int size; // last used element
private final int dim;
private final float growFactor;
public FloatTupleArrayImpl(int dim, int initialSize) {
this(dim, initialSize, DEF_GROW_FACTOR);
}
/**
* Construct an instance of <code>initialSize</code>.
* @param dim The tuple dimension.
* @param initialSize The initial size of the internal array.
* @param growFactor Factor to grow by when resizing is necessary.
*/
public FloatTupleArrayImpl(int dim, int initialSize, float growFactor) {
assert initialSize > 1;
this.dim = dim;
elements = new float[dim][initialSize];
this.growFactor = growFactor;
}
/**
* Grow the internal arrays. <code>System.arraycopy</code> is used for array
* expansion.
*/
protected void grow() {
int newSize = (int)(elements[0].length * growFactor);
log.fine("growing from " + elements[0].length + " to "+newSize);
float[][] newArr = new float[elements.length][newSize];
for (int i = 0; i < elements.length; i++) {
System.arraycopy(elements[i], 0, newArr[i], 0, elements[0].length);
}
elements = newArr;
newArr = null;
}
/**
* Add values. If there is not enough space for the number of values to be
* added the array is continually grown until there is room.
* @param values Source array.
* @param start index in the source array to start at
* @param num number of values to add.
*/
public void add(float[][] values, int start, int num) {
int spaceLeft = this.elements[0].length - size;
while (spaceLeft < num) {
grow();
spaceLeft = this.elements[0].length - size;
}
for (int i = 0; i < this.dim; i++) {
System.arraycopy(values[i], start, this.elements[i], size, num);
}
size += num;
}
/**
* Reference to the backing data array. Any changes made to this array will be
* reflected in the actual data.
*/
public float[][] elements() {
return elements;
}
/**
* Add values. If there is not enough space for the number of values to be
* added the array is continually grown until there is room.
* @param values Source array.
*/
public void add(float[][] values) {
add(values, 0, values[0].length);
}
/**
* Set a value.
* @param i dimension index of the values to set
* @param j tuple index of the value to set
* @param val the value
*/
public void set(int i, int j, float val) {
assert i < dim;
assert j < size;
elements[i][j] = val;
}
/**
* Get a tuple.
* @param idx The index of the tuple
* @return an array of the tuple values at the provided index.
*/
public float[] get(int idx) {
assert idx >= 0 && idx < size;
float[] point = new float[dim()];
for (int i = 0; i < dim(); i++) {
point[i] = elements[i][idx];
}
return point;
}
/**
* Get a value.
* @param i dimension index
* @param j tuple index.
*/
public float get(int i, int j) {
assert i < elements.length;
assert i < size;
return elements[i][j];
}
/**
* Get contained data as array. The size of the array is exactly the size of the
* data.
* <p>
* NOTE: This is an expensive operation.
*/
public float[][] toArray() {
float[][] ret = new float[dim][size];
for (int i = 0; i < dim; i++) {
System.arraycopy(elements[i], 0, ret[i], 0, size);
}
return ret;
}
/**
* Get the size of the valid data.
*/
public int size() {
return size;
}
/**
* Get the dimension of the tuple.
*/
public int dim() {
return dim;
}
}