Hello,

     A colleague at IBM recently sent me private e-mail about exceptions 
that were being thrown in non-exceptional circumstances in 
DeferredDocumentImpl.ensureCapacity().  Last year, after she pointed out 
the cost of testing array capacity in this way, I made some effort to 
submit patches for Xerces-1 to eliminate them where appropriate.  This is 
an instance that was lingering in Xerces-2.

     This patch to DeferredDocumentImpl seems to improve parsing with 
deferred DOM up to a few per cent, depending on the document, JDK, etc.



     I noticed some other ensureCapacity methods in DOMNodePool that have 
the same problem, but they're probably not as important, as the sizes of 
the affected tables are likely to remain relatively stable from one parse 
to the next.  However, one never knows whether someone might use this as a 
model, so I've supplied a patch for it as well.



     There are probably some other instances of this lurking about; I'll 
likely submit some additional patches in the next few days.

     I'd appreciate it if someone could review and commit these patches 
(or comment, if appropriate.)

Thanks,

Henry
------------------------------------------------------------------
Henry Zongaro      XML Parsers development
IBM SWS Toronto Lab   Tie Line 969-6044;  Phone (905) 413-6044
mailto:[EMAIL PROTECTED]
Index: xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMNodePool.java
===================================================================
RCS file: 
/home/cvspublic/xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMNodePool.java,v
retrieving revision 1.1
diff -u -r1.1 DOMNodePool.java
--- xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMNodePool.java  3 Apr 2002 
23:48:27 -0000       1.1
+++ xml-xerces/java/src/org/apache/xerces/impl/xs/dom/DOMNodePool.java  26 Apr 2002 
+19:25:18 -0000
@@ -117,17 +117,16 @@
         return fElements[chunk][index];
     }
 
-    private boolean ensureElementsCapacity(int chunk) {
-        try {
-            return fElements[chunk][0] == null;
-        } catch (ArrayIndexOutOfBoundsException ex) {
+    private void ensureElementsCapacity(int chunk) {
+        if (fElements.length <= chunk) {
             fElements = resize(fElements, fElements.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
+        }
+        else if (fElements[chunk] != null) {
+            return;
         }
 
         fElements[chunk] = new ElementNSImpl[CHUNK_SIZE];
-        return true;
+        return;
     }
 
     private static ElementNSImpl[][] resize(ElementNSImpl array[][], int newsize) {
@@ -153,17 +152,16 @@
         return fTextNode[chunk][index];
     }
 
-    private boolean ensureTextCapacity(int chunk) {
-        try {
-            return fTextNode[chunk][0] == null;
-        } catch (ArrayIndexOutOfBoundsException ex) {
+    private void ensureTextCapacity(int chunk) {
+        if (fTextNode.length <= chunk) {
             fTextNode = resize(fTextNode, fTextNode.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
+        }
+        else if (fTextNode[chunk] != null) {
+            return;
         }
 
         fTextNode[chunk] = new TextImpl[CHUNK_SIZE];
-        return true;
+        return;
     }
 
     private static TextImpl[][] resize(TextImpl array[][], int newsize) {
@@ -189,17 +187,16 @@
         return fAttrNode[chunk][index];
     }
 
-    private boolean ensureAttrsCapacity(int chunk) {
-        try {
-            return fAttrNode[chunk][0] == null;
-        } catch (ArrayIndexOutOfBoundsException ex) {
+    private void ensureAttrsCapacity(int chunk) {
+        if (fAttrNode.length <= chunk) {
             fAttrNode = resize(fAttrNode, fAttrNode.length * 2);
-        } catch (NullPointerException ex) {
-            // ignore
+        }
+        else if (fAttrNode[chunk] != null) {
+            return;
         }
 
         fAttrNode[chunk] = new AttrNSImpl[CHUNK_SIZE];
-        return true;
+        return;
     }
 
     private static AttrNSImpl[][] resize(AttrNSImpl array[][], int newsize) {
Index: xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentImpl.java
===================================================================
RCS file: 
/home/cvspublic/xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentImpl.java,v
retrieving revision 1.44
diff -u -r1.44 DeferredDocumentImpl.java
--- xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentImpl.java 26 Apr 2002 
18:32:57 -0000      1.44
+++ xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentImpl.java 30 Apr 2002 
+19:18:50 -0000
@@ -1630,10 +1630,9 @@
     // utility methods
 
     /** Ensures that the internal tables are large enough. */
-    protected boolean ensureCapacity(int chunk, int index) {
-
-        // create buffers
+    protected void ensureCapacity(int chunk, int index) {
         if (fNodeType == null) {
+            // create buffers
             fNodeType       = new int[INITIAL_CHUNK_COUNT][];
             fNodeName       = new Object[INITIAL_CHUNK_COUNT][];
             fNodeValue      = new Object[INITIAL_CHUNK_COUNT][];
@@ -1643,14 +1642,8 @@
             fNodeURI        = new Object[INITIAL_CHUNK_COUNT][];
             fNodeExtra      = new int[INITIAL_CHUNK_COUNT][];
         }
-
-        // return true if table is already big enough
-        try {
-            return fNodeType[chunk][index] != 0;
-        }
-
-        // resize the tables
-        catch (ArrayIndexOutOfBoundsException ex) {
+        else if (fNodeType.length <= chunk) {
+            // resize tables
             int newsize = chunk * 2;
 
             int[][] newArray = new int[newsize][];
@@ -1685,12 +1678,12 @@
             System.arraycopy(fNodeExtra, 0, newArray, 0, chunk);
             fNodeExtra = newArray;
         }
-
-        catch (NullPointerException ex) {
-            // ignore
+        else if (fNodeType[chunk] != null) {
+            // Done - there's sufficient capacity
+            return;
         }
 
-        // create chunks
+        // create new chunks
         createChunk(fNodeType, chunk);
         createChunk(fNodeName, chunk);
         createChunk(fNodeValue, chunk);
@@ -1700,10 +1693,10 @@
         createChunk(fNodeURI, chunk);
         createChunk(fNodeExtra, chunk);
 
-        // success
-        return true;
+        // Done
+        return;
 
-    } // ensureCapacity(int,int):boolean
+    } // ensureCapacity(int,int)
 
     /** Creates a node of the specified type. */
     protected int createNode(short nodeType) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to