[6:37:22 AM] Jackie de Vries: * http://www.opensource.org/licenses/eclipse-1.0.php
/**
* This is a basic utility for buffering the elements of a rank-1 Array
* of unpredictable size. It implements the Builder interface and
* virtually nothing else.
*/
* @param initialCapacity the number of entries in the buffer initially
/**
* This is a basic utility for buffering the elements of a rank-1 Array
* of unpredictable size. It implements the Builder interface and
* virtually nothing else.
*/
public class ArrayBuilder[T] implements x10.util.Builder[T, Array[T]] {
/** how many entries to allow by default in the initial buffer */
public static DEFAULT_INITIAL_CAPACITY = 16;
/** the default factor to multiply the capacity by when growing the buffer */
public static DEFAULT_GROWTH_RATE = 2.0;
private var buffer: Array[T](1);
private var size: Int = 0; // the number of entries added
private val maximumCapacity: Int; // don't let the buffer grow beyond this size
private val growthRate: Double; // what to multiply the capacity by when growing the buffer
/**
* create a builder with the default initial capacity and growth rate,
* and no capacity bound
*/
public def this() {
this(DEFAULT_INITIAL_CAPACITY, Int.MAX_VALUE, DEFAULT_GROWTH_RATE);
}
/**
* create a builder with the default growth rate and no capacity bound,
* but with the given initial capacity
* @param initialCapacity the number of entries in the buffer initially
*/
public def this(initialCapacity: Int) {
this(initialCapacity, Int.MAX_VALUE, DEFAULT_GROWTH_RATE);
}
/**
* create a builder with the default growth rate, but with
* the given initial capacity and overall capacity bound
* @param initialCapacity the number of entries in the buffer initially
* @param maximumCapacity do not allow more than this many entries
*/
public def this(initialCapacity: Int, maximumCapacity: Int) {
this(initialCapacity, maximumCapacity, DEFAULT_GROWTH_RATE);
}
/**
* create a builder with all of the parameters specified.
* @param initialCapacity the number of entries in the buffer initially
* @param maximumCapacity do not allow more than this many entries
* @param growthRate what to multiply the capacity by when growing the buffer
*/
public def this(initialCapacity: Int, maximumCapacity: Int, growthRate: Double) {
if (initialCapacity > maximumCapacity) {
val msg = "Initial capacity, " +initialCapacity+
", exceeds the maximum, "+maximumCapacity;
throw new IllegalArgumentException(msg);
}
buffer = new Array[T](0..initialCapacity-1);
this.maximumCapacity = maximumCapacity;
this.growthRate = growthRate;
}
/**
* add an entry, growing the buffer if need be
* @param t the new item to be added
* @return this builder
*/
public def add(t: T): ArrayBuilder[T] {
if (this.size >= buffer.size) growTheBuffer();
buffer(this.size++) = t;
return this;
}
/**
* return the current number of entries in the whole buffer
* @return the currentnumber of entries in the whole buffer
*/
public def capacity() = buffer.size;
/**
* return the entries indexed by 0 through size-1 as an array
* @return the entries indexed by 0 through size-1 as an array
*/
public def result(): Array[T](1) {
return new Array[T](size, (n: Int)=>buffer((n)));
}
/**
* return the number of entries added to the buffer
* @return the number of entries added to the buffer
*/
public def size() = this.size;
/**
* a new buffer array is created whose capacity is the current
* capacity multiplied by the growthRate, and then the current
* entries are copied into the new buffer.
*/
public def growTheBuffer() {
if (buffer.size >= maximumCapacity) {
val msg = "Maximum capacity, "+maximumCapacity+" exceeded.";
throw new IllegalArgumentException(msg);
}
var newSize:Int = Math.floor(growthRate*buffer.size) as Int;
if (newSize >= maximumCapacity) newSize = maximumCapacity;
val newBuffer = new Array[T](newSize);
Array.copy(buffer, 0, newBuffer, 0, size);
}
}