/*
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 initialSize.
   * @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. System.arraycopy 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. 
   * 

* 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; } }

Ads help maintain this website.