You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2008/12/14 17:31:59 UTC

svn commit: r726490 - in /commons/proper/math/trunk/src: java/org/apache/commons/math/linear/SparseRealMatrix.java java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java

Author: luc
Date: Sun Dec 14 08:31:58 2008
New Revision: 726490

URL: http://svn.apache.org/viewvc?rev=726490&view=rev
Log:
removed overhead of Entry object allocation during OpenIntToDoubleHashMap iteration

Modified:
    commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SparseRealMatrix.java
    commons/proper/math/trunk/src/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java
    commons/proper/math/trunk/src/test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SparseRealMatrix.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SparseRealMatrix.java?rev=726490&r1=726489&r2=726490&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SparseRealMatrix.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/SparseRealMatrix.java Sun Dec 14 08:31:58 2008
@@ -104,10 +104,10 @@
 
         final RealMatrix out = new SparseRealMatrix(this);
         for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
-            final OpenIntToDoubleHashMap.Entry entry = iterator.next();
-            final int row = entry.key() / columnDimension;
-            final int col = entry.key() - row * columnDimension;
-            out.setEntry(row, col, getEntry(row, col) + entry.value());
+            iterator.advance();
+            final int row = iterator.key() / columnDimension;
+            final int col = iterator.key() - row * columnDimension;
+            out.setEntry(row, col, getEntry(row, col) + iterator.value());
         }
 
         return out;
@@ -138,10 +138,10 @@
 
         final RealMatrix out = new SparseRealMatrix(this);
         for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
-            final OpenIntToDoubleHashMap.Entry entry = iterator.next();
-            final int row = entry.key() / columnDimension;
-            final int col = entry.key() - row * columnDimension;
-            out.setEntry(row, col, getEntry(row, col) - entry.value());
+            iterator.advance();
+            final int row = iterator.key() / columnDimension;
+            final int col = iterator.key() - row * columnDimension;
+            out.setEntry(row, col, getEntry(row, col) - iterator.value());
         }
 
         return out;

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java?rev=726490&r1=726489&r2=726490&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java Sun Dec 14 08:31:58 2008
@@ -456,16 +456,28 @@
         /** Reference modification count. */
         final int referenceCount;
 
+        /** Index of curent element. */
+        private int current;
+
         /** Index of next element. */
-        private int index;
+        private int next;
 
         /**
          * Simple constructor.
          */
         private Iterator() {
+
+            // preserve the modification count of the map to detect concurrent modifications later
             referenceCount = count;
-            index = -1;
-            goToNext();
+
+            // initialize current index
+            next = -1;
+            try {
+                advance();
+            } catch (NoSuchElementException nsee) {
+                // ignored
+            }
+
         }
 
         /**
@@ -473,81 +485,73 @@
          * @return true if there is a next element
          */
         public boolean hasNext() {
-            return index >= 0;
+            return next >= 0;
         }
 
         /**
-         * Get the next entry.
-         * @return next entry
+         * Get the key of current entry.
+         * @return key of current entry
          * @exception ConcurrentModificationException if the map is modified during iteration
          * @exception NoSuchElementException if there is no element left in the map
          */
-        public Entry next()
+        public int key()
             throws ConcurrentModificationException, NoSuchElementException {
             if (referenceCount != count) {
                 throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating",
                                                                                  null);
             }
-            if (index < 0) {
+            if (current < 0) {
                 throw MathRuntimeException.createNoSuchElementException("iterator exhausted", null);
             }
-            final Entry entry = new Entry(keys[index], values[index]);
-            goToNext();
-            return entry;
+            return keys[current];
         }
 
         /**
-         * Find next index.
+         * Get the value of current entry.
+         * @return value of current entry
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
          */
-        private void goToNext() {
-            try {
-                while (states[++index] != FULL) {
-                    // nothing to do
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                index = -1;
+        public double value()
+            throws ConcurrentModificationException, NoSuchElementException {
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating",
+                                                                                 null);
+            }
+            if (current < 0) {
+                throw MathRuntimeException.createNoSuchElementException("iterator exhausted", null);
             }
+            return values[current];
         }
 
-    }
-
-    /** Entry class for the map.
-     * <p>Entry elements are built on the fly only during iteration,
-     * copying values. So changes in the map are <strong>not</strong>
-     * reflected on already built entries.</p>
-     */
-    public static class Entry {
-
-        /** Key. */
-        private final int key;
-
-        /** Value. */
-        private final double value;
-
         /**
-         * Simple constructor.
-         * @param key entry key
-         * @param value entry value
+         * Advance iterator one step further.
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
          */
-        private Entry(final int key, final double value) {
-            this.key   = key;
-            this.value = value;
-        }
+        public void advance()
+            throws ConcurrentModificationException, NoSuchElementException {
 
-        /**
-         * Get the key.
-         * @return entry key
-         */
-        public int key() {
-            return key;
-        }
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException("map has been modified while iterating",
+                                                                                 null);
+            }
+
+            // advance on step
+            current = next;
+
+            // prepare next step
+            try {
+                while (states[++next] != FULL) {
+                    // nothing to do
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                next = -2;
+                if (current < 0) {
+                    throw MathRuntimeException.createNoSuchElementException("iterator exhausted", null);
+                }
+            }
 
-        /**
-         * Get the value.
-         * @return entry value
-         */
-        public double value() {
-            return value;
         }
 
     }

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java?rev=726490&r1=726489&r2=726490&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/util/OpenIntToDoubleHashMapTest.java Sun Dec 14 08:31:58 2008
@@ -228,15 +228,17 @@
         OpenIntToDoubleHashMap.Iterator iterator = map.iterator();
         for (int i = 0; i < map.size(); ++i) {
             assertTrue(iterator.hasNext());
-            OpenIntToDoubleHashMap.Entry entry = iterator.next();
-            int key = entry.key();
+            iterator.advance();
+            int key = iterator.key();
             assertTrue(map.containsKey(key));
             assertEquals(javaMap.get(key), map.get(key), 0);
+            assertEquals(javaMap.get(key), iterator.value(), 0);
             assertTrue(javaMap.containsKey(key));
         }
         assertFalse(iterator.hasNext());
         try {
-            iterator.next();
+            iterator.advance();
+            fail("an exception should have been thrown");
         } catch (NoSuchElementException nsee) {
             // expected
         }
@@ -247,7 +249,8 @@
         OpenIntToDoubleHashMap.Iterator iterator = map.iterator();
         map.put(3, 3);
         try {
-            iterator.next();
+            iterator.advance();
+            fail("an exception should have been thrown");
         } catch (ConcurrentModificationException cme) {
             // expected
         }