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));


Reply via email to