Author: erans
Date: Wed Nov 14 22:13:54 2012
New Revision: 1409475
URL: http://svn.apache.org/viewvc?rev=1409475&view=rev
Log:
MATH-894
Added new "protected" (and not "synchronized") methods to allow access to
the internal array for subclasses only.
Javadoc formatting.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ResizableDoubleArray.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ResizableDoubleArrayTest.java
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ResizableDoubleArray.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ResizableDoubleArray.java?rev=1409475&r1=1409474&r2=1409475&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ResizableDoubleArray.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/ResizableDoubleArray.java
Wed Nov 14 22:13:54 2012
@@ -33,19 +33,20 @@ import org.apache.commons.math3.exceptio
* are added and removed.
* </p>
* <p>
- * The internal storage array starts with capacity determined by the
- * <code>initialCapacity</code> property, which can be set by the constructor.
+ * The internal storage array starts with capacity determined by the
+ * {@code initialCapacity} property, which can be set by the constructor.
* The default initial capacity is 16. Adding elements using
- * {@link #addElement(double)} appends elements to the end of the array. When
- * there are no open entries at the end of the internal storage array, the
- * array is expanded. The size of the expanded array depends on the
- * <code>expansionMode</code> and <code>expansionFactor</code> properties.
- * The <code>expansionMode</code> determines whether the size of the array is
- * multiplied by the <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if
- * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code>
- * storage locations added). The default <code>expansionMode</code> is
- * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code>
- * is 2.0.
+ * {@link #addElement(double)} appends elements to the end of the array.
+ * When there are no open entries at the end of the internal storage array,
+ * the array is expanded. The size of the expanded array depends on the
+ * {@code expansionMode} and {@code expansionFactor} properties.
+ * The {@code expansionMode} determines whether the size of the array is
+ * multiplied by the {@code expansionFactor}
+ * ({@link ExpansionMode#MULTIPLICATIVE}) or if the expansion is additive
+ * ({@link ExpansionMode#ADDITIVE} -- {@code expansionFactor} storage
+ * locations added).
+ * The default {@code expansionMode} is {@code MULTIPLICATIVE} and the default
+ * {@code expansionFactor} is 2.
* </p>
* <p>
* The {@link #addElementRolling(double)} method adds a new element to the end
@@ -56,23 +57,23 @@ import org.apache.commons.math3.exceptio
* the storage locations at the beginning of the internal storage array. To
* reclaim this storage, each time one of these methods is activated, the size
* of the internal storage array is compared to the number of addressable
- * elements (the <code>numElements</code> property) and if the difference
+ * elements (the {@code numElements} property) and if the difference
* is too large, the internal array is contracted to size
- * <code>numElements + 1.</code> The determination of when the internal
- * storage array is "too large" depends on the <code>expansionMode</code> and
- * <code>contractionFactor</code> properties. If the
<code>expansionMode</code>
- * is <code>MULTIPLICATIVE</code>, contraction is triggered when the
- * ratio between storage array length and <code>numElements</code> exceeds
- * <code>contractionFactor.</code> If the <code>expansionMode</code>
- * is <code>ADDITIVE</code>, the number of excess storage locations
- * is compared to <code>contractionFactor.</code>
+ * {@code numElements + 1}. The determination of when the internal
+ * storage array is "too large" depends on the {@code expansionMode} and
+ * {@code contractionFactor} properties. If the {@code expansionMode}
+ * is {@code MULTIPLICATIVE}, contraction is triggered when the
+ * ratio between storage array length and {@code numElements} exceeds
+ * {@code contractionFactor.} If the {@code expansionMode}
+ * is {@code ADDITIVE}, the number of excess storage locations
+ * is compared to {@code contractionFactor}.
* </p>
* <p>
* To avoid cycles of expansions and contractions, the
- * <code>expansionFactor</code> must not exceed the
- * <code>contractionFactor.</code> Constructors and mutators for both of these
- * properties enforce this requirement, throwing IllegalArgumentException if it
- * is violated.
+ * {@code expansionFactor} must not exceed the {@code contractionFactor}.
+ * Constructors and mutators for both of these properties enforce this
+ * requirement, throwing a {@code MathIllegalArgumentException} if it is
+ * violated.
* </p>
* @version $Id$
*/
@@ -105,15 +106,15 @@ public class ResizableDoubleArray implem
/**
* The expansion factor of the array. When the array needs to be expanded,
* the new array size will be
- * <code>internalArray.length * expansionFactor</code>
- * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, or
- * <code>internalArray.length + expansionFactor</code> if
- * <code>expansionMode</code> is set to ADDITIVE_MODE.
+ * {@code internalArray.length * expansionFactor}
+ * if {@code expansionMode} is set to MULTIPLICATIVE_MODE, or
+ * {@code internalArray.length + expansionFactor} if
+ * {@code expansionMode} is set to ADDITIVE_MODE.
*/
private float expansionFactor = 2.0f;
/**
- * Determines whether array expansion by <code>expansionFactor</code>
+ * Determines whether array expansion by {@code expansionFactor}
* is additive or multiplicative.
*/
private ExpansionMode expansionMode = ExpansionMode.MULTIPLICATIVE;
@@ -137,9 +138,8 @@ public class ResizableDoubleArray implem
/**
* The position of the first addressable element in the internal storage
- * array. The addressable elements in the array are <code>
- * internalArray[startIndex],...,internalArray[startIndex + numElements -1]
- * </code>
+ * array. The addressable elements in the array are
+ * {@code internalArray[startIndex],...,internalArray[startIndex +
numElements - 1]}.
*/
private int startIndex = 0;
@@ -162,8 +162,7 @@ public class ResizableDoubleArray implem
* <li>{@code contractionFactor = 2.5}</li>
* </ul>
*/
- public ResizableDoubleArray()
- throws MathIllegalArgumentException {
+ public ResizableDoubleArray() {
this(DEFAULT_INITIAL_CAPACITY);
}
@@ -761,6 +760,44 @@ public class ResizableDoubleArray implem
}
/**
+ * Provides <em>direct</em> access to the internal storage array.
+ * Please note that this method returns a reference to this object's
+ * storage array, not a copy.
+ * <br/>
+ * To correctly address elements of the array, the "start index" is
+ * required (available via the {@link #getStartIndex() getStartIndex}
+ * method.
+ * <br/>
+ * This method should only be used to avoid copying the internal array.
+ * The returned value <em>must</em> be used for reading only; other
+ * uses could lead to this object becoming inconsistent.
+ * <br/>
+ * The {@link #getElements} method has no such limitation since it
+ * returns a copy of this array's addressable elements.
+ *
+ * @return the internal storage array used by this object.
+ * @since 3.1
+ */
+ protected double[] getArrayRef() {
+ return internalArray;
+ }
+
+ /**
+ * Returns the "start index" of the internal array.
+ * This index is the position of the first addressable element in the
+ * internal storage array.
+ * The addressable elements in the array are at indices contained in
+ * the interval [{@link #getStartIndex()},
+ * {@link #getStartIndex()} + {@link #getNumElements()} - 1].
+ *
+ * @return the start index.
+ * @since 3.1
+ */
+ protected int getStartIndex() {
+ return startIndex;
+ }
+
+ /**
* Sets the contraction criteria.
*
* @param contractionCriteria contraction criteria
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ResizableDoubleArrayTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ResizableDoubleArrayTest.java?rev=1409475&r1=1409474&r2=1409475&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ResizableDoubleArrayTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/util/ResizableDoubleArrayTest.java
Wed Nov 14 22:13:54 2012
@@ -541,6 +541,23 @@ public class ResizableDoubleArrayTest ex
}
+ @Test
+ public void testGetArrayRef() {
+ final ResizableDoubleArray a = new ResizableDoubleArray();
+
+ // Modify "a" through the public API.
+ final int index = 20;
+ final double v1 = 1.2;
+ a.setElement(index, v1);
+
+ // Modify the internal storage through the protected API.
+ final double v2 = v1 + 3.4;
+ final double[] aInternalArray = a.getArrayRef();
+ aInternalArray[a.getStartIndex() + index] = v2;
+
+ Assert.assertEquals(v2, a.getElement(index), 0d);
+ }
+
private void verifyEquality(ResizableDoubleArray a, ResizableDoubleArray
b) {
Assert.assertTrue(b.equals(a));
Assert.assertTrue(a.equals(b));