ASF Bugzilla – Attachment 25231 Details for
Bug 49050
[PATCH] Inefficient concatenation of ContinueRecord contents in AbstractEscherHolderRecord
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch
continue-record-concatenation.patch (text/plain), 6.42 KB, created by
Trejkaz (pen name)
on 2010-04-06 03:52:15 UTC
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Trejkaz (pen name)
Created:
2010-04-06 03:52:15 UTC
Size:
6.42 KB
patch
obsolete
>Index: src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java >=================================================================== >--- src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java (revision 0) >+++ src/java/org/apache/poi/hssf/util/LazilyConcatenatedByteArray.java (revision 0) >@@ -0,0 +1,82 @@ >+/* ==================================================================== >+ Licensed to the Apache Software Foundation (ASF) under one or more >+ contributor license agreements. See the NOTICE file distributed with >+ this work for additional information regarding copyright ownership. >+ The ASF licenses this file to You under the Apache License, Version 2.0 >+ (the "License"); you may not use this file except in compliance with >+ the License. You may obtain a copy of the License at >+ >+ http://www.apache.org/licenses/LICENSE-2.0 >+ >+ Unless required by applicable law or agreed to in writing, software >+ distributed under the License is distributed on an "AS IS" BASIS, >+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >+ See the License for the specific language governing permissions and >+ limitations under the License. >+==================================================================== */ >+ >+ >+package org.apache.poi.hssf.util; >+ >+import java.util.ArrayList; >+import java.util.List; >+ >+/** >+ * Utility for delaying the concatenation of multiple byte arrays. Doing thit up-front >+ * causes significantly more copying, which for a large number of byte arrays can cost >+ * a large amount of time. >+ * >+ * @author Trejkaz (trejkaz at trypticon.org) >+ */ >+public class LazilyConcatenatedByteArray { >+ private final List<byte[]> arrays = new ArrayList<byte[]>(1); >+ >+ /** >+ * Clears the array (sets the concatenated length back to zero. >+ */ >+ public void clear() { >+ arrays.clear(); >+ } >+ >+ /** >+ * Concatenates an array onto the end of our array. >+ * This is a relatively fast operation. >+ * >+ * @param array the array to concatenate. >+ */ >+ public void concatenate(byte[] array) { >+ arrays.add(array); >+ } >+ >+ /** >+ * Gets the concatenated contents as a single byte array. >+ * >+ * This is a slower operation, but the concatenated array is stored off as a single >+ * array again so that subsequent calls will not perform additional copying. >+ * >+ * @return the byte array. Returns {@code null} if no data has been placed into it. >+ */ >+ public byte[] toArray() { >+ if (arrays.isEmpty()) { >+ return null; >+ } else if (arrays.size() > 1) { >+ int totalLength = 0; >+ for (byte[] array : arrays) { >+ totalLength += array.length; >+ } >+ >+ byte[] concatenated = new byte[totalLength]; >+ int destPos = 0; >+ for (byte[] array : arrays) { >+ System.arraycopy(array, 0, concatenated, destPos, array.length); >+ destPos += array.length; >+ } >+ >+ arrays.clear(); >+ arrays.add(concatenated); >+ } >+ >+ return arrays.get(0); >+ } >+} >+ >Index: src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java >=================================================================== >--- src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java (revision 10428) >+++ src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java (working copy) >@@ -28,6 +28,7 @@ > import org.apache.poi.ddf.EscherRecordFactory; > import org.apache.poi.ddf.NullEscherSerializationListener; > import org.apache.poi.util.LittleEndian; >+import org.apache.poi.hssf.util.LazilyConcatenatedByteArray; > > /** > * The escher container record is used to hold escher records. It is abstract and >@@ -47,7 +48,7 @@ > } > > private List escherRecords; >- private byte[] rawData; >+ private LazilyConcatenatedByteArray rawDataContainer = new LazilyConcatenatedByteArray(); > > > public AbstractEscherHolderRecord() >@@ -60,7 +61,7 @@ > escherRecords = new ArrayList(); > if (! DESERIALISE ) > { >- rawData = in.readRemainder(); >+ rawDataContainer.concatenate(in.readRemainder()); > } > else > { >@@ -70,6 +71,7 @@ > } > > protected void convertRawBytesToEscherRecords() { >+ byte[] rawData = getRawData(); > convertToEscherRecords(0, rawData.length, rawData); > } > private void convertToEscherRecords( int offset, int size, byte[] data ) >@@ -109,6 +111,7 @@ > { > LittleEndian.putShort( data, 0 + offset, getSid() ); > LittleEndian.putShort( data, 2 + offset, (short) ( getRecordSize() - 4 ) ); >+ byte[] rawData = getRawData(); > if ( escherRecords.size() == 0 && rawData != null ) > { > LittleEndian.putShort(data, 0 + offset, getSid()); >@@ -129,7 +132,9 @@ > } > > public int getRecordSize() { >+ byte[] rawData = getRawData(); > if (escherRecords.size() == 0 && rawData != null) { >+ // XXX: It should be possible to derive this without concatenating the array, too. > return rawData.length; > } > int size = 0; >@@ -229,30 +234,23 @@ > */ > public void join( AbstractEscherHolderRecord record ) > { >- int length = this.rawData.length + record.getRawData().length; >- byte[] data = new byte[length]; >- System.arraycopy( rawData, 0, data, 0, rawData.length ); >- System.arraycopy( record.getRawData(), 0, data, rawData.length, record.getRawData().length ); >- rawData = data; >+ rawDataContainer.concatenate(record.getRawData()); > } > > public void processContinueRecord( byte[] record ) > { >- int length = this.rawData.length + record.length; >- byte[] data = new byte[length]; >- System.arraycopy( rawData, 0, data, 0, rawData.length ); >- System.arraycopy( record, 0, data, rawData.length, record.length ); >- rawData = data; >+ rawDataContainer.concatenate(record); > } > > public byte[] getRawData() > { >- return rawData; >+ return rawDataContainer.toArray(); > } > > public void setRawData( byte[] rawData ) > { >- this.rawData = rawData; >+ rawDataContainer.clear(); >+ rawDataContainer.concatenate(rawData); > } > > /** >@@ -260,6 +258,7 @@ > */ > public void decode() > { >+ byte[] rawData = getRawData(); > convertToEscherRecords(0, rawData.length, rawData ); > } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 49050
:
25231
|
25232