Author: nick
Date: Fri Jul  1 16:16:55 2011
New Revision: 1141970

URL: http://svn.apache.org/viewvc?rev=1141970&view=rev
Log:
Apply patch from bug #51460 (with some related generics tweaks) - Improve HSSF 
performance when loading very long rows, by switching the CellValue array to an 
iterator

Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
    poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java
    
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
    
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Fri Jul  1 16:16:55 
2011
@@ -34,7 +34,8 @@
 
     <changes>
         <release version="3.8-beta4" date="2011-??-??">
-           <action dev="poi-developers" type="add">51444 - Prevent corrupted 
output when saving files created by LibreOffice 3.3 </action>
+           <action dev="poi-developers" type="add">51460 - Improve HSSF 
performance when loading very long rows, by switching the CellValue array to an 
iterator</action>
+           <action dev="poi-developers" type="fix">51444 - Prevent corrupted 
output when saving files created by LibreOffice 3.3 </action>
            <action dev="poi-developers" type="add">51422 - Support using 
RecalcIdRecord to trigger a full formula recalculation on load  </action>
            <action dev="poi-developers" type="add">50474 - Example 
demonstrating how to update Excel workbook embedded in a WordprocessingML 
document </action>
            <action dev="poi-developers" type="fix">51431 - Avoid 
IndexOutOfBoundException when removing freeze panes in XSSF </action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java Fri Jul  1 
16:16:55 2011
@@ -360,13 +360,13 @@ public final class InternalSheet {
 
     private static final class RecordCloner implements RecordVisitor {
 
-        private final List<RecordBase> _destList;
+        private final List<Record> _destList;
 
-        public RecordCloner(List<RecordBase> destList) {
+        public RecordCloner(List<Record> destList) {
             _destList = destList;
         }
         public void visitRecord(Record r) {
-            _destList.add((RecordBase)r.clone());
+            _destList.add((Record)r.clone());
         }
     }
 
@@ -378,7 +378,7 @@ public final class InternalSheet {
      * belongs to a sheet.
      */
     public InternalSheet cloneSheet() {
-        List<RecordBase> clonedRecords = new 
ArrayList<RecordBase>(_records.size());
+        List<Record> clonedRecords = new ArrayList<Record>(_records.size());
         for (int i = 0; i < _records.size(); i++) {
             RecordBase rb = _records.get(i);
             if (rb instanceof RecordAggregate) {
@@ -723,10 +723,27 @@ public final class InternalSheet {
     public void removeRow(RowRecord row) {
         _rowsAggregate.removeRow(row);
     }
+    
+    /**
+     * Get all the value records (from LOC). Records will be returned from the 
first
+     *  record (starting at LOC) which is a value record.
+     *
+     * <P>
+     * This method is "loc" sensitive.  Meaning you need to set LOC to where 
you
+     * want it to start searching.  If you don't know do this: 
setLoc(getDimsLoc).
+     * When adding several rows you can just start at the last one by leaving 
loc
+     * at what this sets it to.  For this method, set loc to dimsloc to start 
with,
+     * subsequent calls will return values in (physical) sequence or NULL when 
you get to the end.
+     *
+     * @return Iterator of CellValueRecordInterface representing the value 
records
+     */
+    public Iterator<CellValueRecordInterface> getCellValueIterator(){
+       return _rowsAggregate.getCellValueIterator();
+    }
 
     /**
-     * get the NEXT value record (from LOC).  The first record that is a value 
record
-     * (starting at LOC) will be returned.
+     * Get all the value records (from LOC). Records will be returned from the 
first
+     *  record (starting at LOC) which is a value record.
      *
      * <P>
      * This method is "loc" sensitive.  Meaning you need to set LOC to where 
you
@@ -735,8 +752,10 @@ public final class InternalSheet {
      * at what this sets it to.  For this method, set loc to dimsloc to start 
with,
      * subsequent calls will return values in (physical) sequence or NULL when 
you get to the end.
      *
-     * @return CellValueRecordInterface representing the next value record or 
NULL if there are no more
+     * @return Array of CellValueRecordInterface representing the remaining 
value records
+     * @deprecated use {@link #getValueIterator()} instead
      */
+    @Deprecated
     public CellValueRecordInterface[] getValueRecords() {
         return _rowsAggregate.getValueRecords();
     }

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java Fri Jul  1 
16:16:55 2011
@@ -27,7 +27,7 @@ import org.apache.poi.hssf.record.Record
  */
 public final class RecordStream {
 
-       private final List _list;
+       private final List<Record> _list;
        private int _nextIndex;
        private int _countRead;
        private final int _endIx;
@@ -35,14 +35,14 @@ public final class RecordStream {
        /**
         * Creates a RecordStream bounded by startIndex and endIndex
         */
-       public RecordStream(List inputList, int startIndex, int endIx) {
+       public RecordStream(List<Record> inputList, int startIndex, int endIx) {
                _list = inputList;
                _nextIndex = startIndex;
                _endIx = endIx;
                _countRead = 0;
        }
 
-       public RecordStream(List records, int startIx) {
+       public RecordStream(List<Record> records, int startIx) {
                this(records, startIx, records.size());
        }
 
@@ -61,7 +61,7 @@ public final class RecordStream {
        /**
         * @return the {@link Class} of the next Record. <code>null</code> if 
this stream is exhausted.
         */
-       public Class peekNextClass() {
+       public Class<? extends Record> peekNextClass() {
                if(!hasNext()) {
                        return null;
                }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
 (original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
 Fri Jul  1 16:16:55 2011
@@ -447,7 +447,17 @@ public final class RowRecordsAggregate e
 
                return startHidden;
        }
+       
+       /**
+        * Returns an iterator for the cell values
+        */
+       public Iterator<CellValueRecordInterface> getCellValueIterator() {
+               return _valuesAgg.iterator();
+       }
 
+       /**
+        * @deprecated use {@link #getCellValueIterator()} instead
+        */
        public CellValueRecordInterface[] getValueRecords() {
                return _valuesAgg.getValueRecords();
        }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
 (original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
 Fri Jul  1 16:16:55 2011
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.record.aggregates;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.poi.hssf.model.RecordStream;
@@ -40,7 +41,7 @@ import org.apache.poi.ss.formula.ptg.Ptg
  * @author  Glen Stampoultzis (glens at apache.org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public final class ValueRecordsAggregate {
+public final class ValueRecordsAggregate implements 
Iterable<CellValueRecordInterface> {
        private static final int MAX_ROW_INDEX = 0XFFFF;
        private static final int INDEX_NOT_SET = -1;
        private int firstcell = INDEX_NOT_SET;
@@ -302,9 +303,66 @@ public final class ValueRecordsAggregate
        }
 
        /**
+        * iterator for CellValueRecordInterface
+        */
+       class ValueIterator implements Iterator<CellValueRecordInterface> {
+
+               int curRowIndex = 0, curColIndex = -1;
+               int nextRowIndex = 0, nextColIndex = -1;
+
+               public ValueIterator() {
+                       getNextPos();
+               }
+
+               void getNextPos() {
+                       if (nextRowIndex >= records.length)
+                               return; // no next already
+
+                       while (nextRowIndex < records.length) {
+                               ++nextColIndex;
+                               if (records[nextRowIndex] == null || 
nextColIndex >= records[nextRowIndex].length) {
+                                       ++nextRowIndex;
+                                       nextColIndex = -1;
+                                       continue;
+                               }
+
+                               if (records[nextRowIndex][nextColIndex] != null)
+                                       return; // next cell found
+                       }
+                       // no next found
+               }
+
+               public boolean hasNext() {
+                       return nextRowIndex < records.length;
+               }
+
+               public CellValueRecordInterface next() {
+                       if (!hasNext())
+                               throw new IndexOutOfBoundsException("iterator 
has no next");
+
+                       curRowIndex = nextRowIndex;
+                       curColIndex = nextColIndex;
+                       final CellValueRecordInterface ret = 
records[curRowIndex][curColIndex];
+                       getNextPos();
+                       return ret;
+               }
+
+               public void remove() {
+                       records[curRowIndex][curColIndex] = null;
+               }
+       }
+
+       /** value iterator */
+       public Iterator<CellValueRecordInterface> iterator() {
+               return new ValueIterator();
+       }
+
+       /**
         * Gets all the cell records contained in this aggregate. 
         * Note {@link BlankRecord}s appear separate (not in {@link 
MulBlankRecord}s).
+        * @deprecated use {@link #iterator()} instead
         */
+       @Deprecated
        public CellValueRecordInterface[] getValueRecords() {
                List<CellValueRecordInterface> temp = new 
ArrayList<CellValueRecordInterface>();
 

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=1141970&r1=1141969&r2=1141970&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Fri Jul  1 
16:16:55 2011
@@ -142,7 +142,7 @@ public final class HSSFSheet implements 
             row = sheet.getNextRow();
         }
 
-        CellValueRecordInterface[] cvals = sheet.getValueRecords();
+        Iterator<CellValueRecordInterface> iter = sheet.getCellValueIterator();
         long timestart = System.currentTimeMillis();
 
         if (log.check( POILogger.DEBUG ))
@@ -151,8 +151,8 @@ public final class HSSFSheet implements 
         HSSFRow lastrow = null;
 
         // Add every cell to its row
-        for (int i = 0; i < cvals.length; i++) {
-            CellValueRecordInterface cval = cvals[i];
+        while (iter.hasNext()) {
+            CellValueRecordInterface cval = iter.next();
 
             long cellstart = System.currentTimeMillis();
             HSSFRow hrow = lastrow;



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to