]> source.dussan.org Git - poi.git/commitdiff
Improved performance of RowRecordsAggregate.getStartRowNumberForBlock / getEndRowNum...
authorYegor Kozlov <yegor@apache.org>
Wed, 8 Dec 2010 16:53:24 +0000 (16:53 +0000)
committerYegor Kozlov <yegor@apache.org>
Wed, 8 Dec 2010 16:53:24 +0000 (16:53 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1043517 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java

index a50f5afdd3d45b3e266e7b2c1bb5f9719acf3710..7854a2adc7166c68e8592887d240d3f77e54b62f 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta1" date="2010-??-??">
+           <action dev="poi-developers" type="add">47405 - Improved performance of RowRecordsAggregate.getStartRowNumberForBlock / getEndRowNumberForBlock</action>
            <action dev="poi-developers" type="add">50315 - Avoid crashing Excel when sorting XSSFSheet autofilter</action>
            <action dev="poi-developers" type="add">50076 - Allow access from XSSFReader to sheet comments and headers/footers</action>
            <action dev="poi-developers" type="add">50076 - Refactor XSSFEventBasedExcelExtractor to make it easier for you to have control over outputting the cell contents</action>
index afe6f2b1b1da5029c12e829c2dc1c025cc4b0ee2..50092cc9ae721bdbfcd762f8cddde9407e0fe844 100644 (file)
@@ -54,6 +54,10 @@ public final class RowRecordsAggregate extends RecordAggregate {
        private final List<Record> _unknownRecords;
        private final SharedValueManager _sharedValueManager;
 
+       // Cache values to speed up performance of
+    // getStartRowNumberForBlock / getEndRowNumberForBlock, see Bugzilla 47405
+    private RowRecord[] _rowRecordValues = null;
+
        /** Creates a new instance of ValueRecordsAggregate */
        public RowRecordsAggregate() {
                this(SharedValueManager.createEmpty());
@@ -121,6 +125,8 @@ public final class RowRecordsAggregate extends RecordAggregate {
        public void insertRow(RowRecord row) {
                // Integer integer = Integer.valueOf(row.getRowNumber());
                _rowRecords.put(Integer.valueOf(row.getRowNumber()), row);
+               // Clear the cached values
+               _rowRecordValues = null; 
                if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) {
                        _firstrow = row.getRowNumber();
                }
@@ -141,6 +147,9 @@ public final class RowRecordsAggregate extends RecordAggregate {
                        _rowRecords.put(key, rr);
                        throw new RuntimeException("Attempt to remove row that does not belong to this sheet");
                }
+               
+               // Clear the cached values
+               _rowRecordValues = null;
        }
 
        public RowRecord getRow(int rowIndex) {
@@ -193,22 +202,17 @@ public final class RowRecordsAggregate extends RecordAggregate {
 
        /** Returns the physical row number of the first row in a block*/
        private int getStartRowNumberForBlock(int block) {
-         //Given that we basically iterate through the rows in order,
-         // TODO - For a performance improvement, it would be better to return an instance of
-         //an iterator and use that instance throughout, rather than recreating one and
-         //having to move it to the right position.
-         int startIndex = block * DBCellRecord.BLOCK_SIZE;
-         Iterator<RowRecord> rowIter = _rowRecords.values().iterator();
-         RowRecord row = null;
-         //Position the iterator at the start of the block
-         for (int i=0; i<=startIndex;i++) {
-               row = rowIter.next();
-         }
-         if (row == null) {
-                 throw new RuntimeException("Did not find start row for block " + block);
-         }
+           int startIndex = block * DBCellRecord.BLOCK_SIZE;
 
-         return row.getRowNumber();
+        if(_rowRecordValues == null){
+            _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]);
+        }
+
+        try {
+            return _rowRecordValues[startIndex].getRowNumber();
+        } catch(ArrayIndexOutOfBoundsException e) {
+                 throw new RuntimeException("Did not find start row for block " + block);
+           }
        }
 
        /** Returns the physical row number of the end row in a block*/
@@ -217,15 +221,15 @@ public final class RowRecordsAggregate extends RecordAggregate {
          if (endIndex >= _rowRecords.size())
                endIndex = _rowRecords.size()-1;
 
-         Iterator<RowRecord> rowIter = _rowRecords.values().iterator();
-         RowRecord row = null;
-         for (int i=0; i<=endIndex;i++) {
-               row = rowIter.next();
-         }
-         if (row == null) {
-                 throw new RuntimeException("Did not find start row for block " + block);
+        if(_rowRecordValues == null){
+            _rowRecordValues = _rowRecords.values().toArray(new RowRecord[_rowRecords.size()]);
+        }
+
+        try {
+            return _rowRecordValues[endIndex].getRowNumber();
+        } catch(ArrayIndexOutOfBoundsException e) {
+            throw new RuntimeException("Did not find end row for block " + block);
          }
-         return row.getRowNumber();
        }
 
        private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) {