You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2016/02/02 23:58:28 UTC

svn commit: r1728233 - in /webservices/axiom/trunk: aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/ code-coverage/ components/xml-utils/src/main/java/org/apache/axiom/util/xml/ components/xml-utils/src/test/java/org/apache/axi...

Author: veithen
Date: Tue Feb  2 22:58:28 2016
New Revision: 1728233

URL: http://svn.apache.org/viewvc?rev=1728233&view=rev
Log:
Use a specialized hash map implementation to store QName/value pairs in order to avoid unnecessary creation of QName instances.

Added:
    webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java   (with props)
    webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java   (with props)
    webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java   (with props)
Modified:
    webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/StAXOMBuilder.java
    webservices/axiom/trunk/code-coverage/pom.xml
    webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMBuilder.java
    webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java

Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/StAXOMBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/StAXOMBuilder.java?rev=1728233&r1=1728232&r2=1728233&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/StAXOMBuilder.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/StAXOMBuilder.java Tue Feb  2 22:58:28 2016
@@ -41,6 +41,7 @@ import org.apache.axiom.om.impl.intf.Axi
 import org.apache.axiom.om.impl.intf.OMFactoryEx;
 import org.apache.axiom.util.stax.XMLEventUtils;
 import org.apache.axiom.util.stax.XMLStreamReaderUtils;
+import org.apache.axiom.util.xml.QNameMap;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -133,7 +134,7 @@ public class StAXOMBuilder implements Bu
     // Fields for Custom Builder implementation
     private final PayloadSelector payloadSelector;
     private CustomBuilder customBuilderForPayload;
-    private Map<QName,CustomBuilder> customBuilders;
+    private QNameMap<CustomBuilder> customBuilders;
     private int maxDepthForCustomBuilders = -1;
     
     /**
@@ -491,7 +492,7 @@ public class StAXOMBuilder implements Bu
     public final CustomBuilder registerCustomBuilder(QName qName, int maxDepth, CustomBuilder customBuilder) {
         CustomBuilder old = null;
         if (customBuilders == null) {
-            customBuilders = new HashMap<QName,CustomBuilder>();
+            customBuilders = new QNameMap<CustomBuilder>();
         } else {
             old = customBuilders.get(qName);
         }
@@ -519,8 +520,7 @@ public class StAXOMBuilder implements Bu
         if (customBuilders == null) {
             return null;
         }
-        QName qName = new QName(namespace, localPart);
-        return customBuilders.get(qName);
+        return customBuilders.get(namespace, localPart);
     }
 
     private void createDocumentIfNecessary() {

Modified: webservices/axiom/trunk/code-coverage/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/code-coverage/pom.xml?rev=1728233&r1=1728232&r2=1728233&view=diff
==============================================================================
--- webservices/axiom/trunk/code-coverage/pom.xml (original)
+++ webservices/axiom/trunk/code-coverage/pom.xml Tue Feb  2 22:58:28 2016
@@ -237,6 +237,25 @@
             <classifier>jacoco</classifier>
             <type>exec</type>
         </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>xml-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>xml-utils</artifactId>
+            <version>${project.version}</version>
+            <classifier>sources</classifier>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>xml-utils</artifactId>
+            <version>${project.version}</version>
+            <classifier>jacoco</classifier>
+            <type>exec</type>
+        </dependency>
     </dependencies>
 
     <build>

Added: webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java?rev=1728233&view=auto
==============================================================================
--- webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java (added)
+++ webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java Tue Feb  2 22:58:28 2016
@@ -0,0 +1,100 @@
+/*
+ * 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.axiom.util.xml;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+public final class QNameMap<V> {
+    private QNameMapEntry<V>[] buckets;
+    private int size;
+    
+    public QNameMap() {
+        buckets = createBuckets(16);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private QNameMapEntry<V>[] createBuckets(int count) {
+        return new QNameMapEntry[count];
+    }
+    
+    public void put(QName qname, V value) {
+        if (buckets.length < size*4/3) {
+            QNameMapEntry<V>[] oldBuckets = buckets;
+            buckets = createBuckets(buckets.length*2);
+            for (QNameMapEntry<V> entry : oldBuckets) {
+                while (entry != null) {
+                    QNameMapEntry<V> next = entry.next;
+                    int index = index(entry.qname);
+                    entry.next = buckets[index];
+                    buckets[index] = entry;
+                    entry = next;
+                }
+            }
+        }
+        int index = index(qname);
+        QNameMapEntry<V> entry = buckets[index];
+        while (entry != null) {
+            if (entry.qname.equals(qname)) {
+                entry.value = value;
+                break;
+            }
+            entry = entry.next;
+        }
+        if (entry == null) {
+            entry = new QNameMapEntry<V>();
+            entry.qname = qname;
+            entry.next = buckets[index];
+            buckets[index] = entry;
+            size++;
+        }
+        entry.value = value;
+    }
+    
+    public V get(QName qname) {
+        return get(qname.getNamespaceURI(), qname.getLocalPart());
+    }
+    
+    public V get(String namespaceURI, String localPart) {
+        if (namespaceURI == null) {
+            namespaceURI = XMLConstants.NULL_NS_URI;
+        }
+        if (localPart == null) {
+            throw new IllegalArgumentException("localPart cannot be null");
+        }
+        int index = index(namespaceURI, localPart);
+        QNameMapEntry<V> entry = buckets[index];
+        while (entry != null) {
+            if (entry.qname.getLocalPart().equals(localPart) &&
+                    entry.qname.getNamespaceURI().equals(namespaceURI)) {
+                return entry.value;
+            }
+            entry = entry.next;
+        }
+        return null;
+    }
+    
+    private int index(QName qname) {
+        return index(qname.getNamespaceURI(), qname.getLocalPart());
+    }
+    
+    private int index(String namespaceURI, String localPart) {
+        return (namespaceURI.hashCode() ^ localPart.hashCode()) & (buckets.length-1);
+    }
+}

Propchange: webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java?rev=1728233&view=auto
==============================================================================
--- webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java (added)
+++ webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java Tue Feb  2 22:58:28 2016
@@ -0,0 +1,27 @@
+/*
+ * 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.axiom.util.xml;
+
+import javax.xml.namespace.QName;
+
+final class QNameMapEntry<V> {
+    QName qname;
+    V value;
+    QNameMapEntry<V> next;
+}

Propchange: webservices/axiom/trunk/components/xml-utils/src/main/java/org/apache/axiom/util/xml/QNameMapEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java?rev=1728233&view=auto
==============================================================================
--- webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java (added)
+++ webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java Tue Feb  2 22:58:28 2016
@@ -0,0 +1,56 @@
+/*
+ * 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.axiom.util.xml;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import javax.xml.namespace.QName;
+
+import org.junit.Test;
+
+public class QNameMapTest {
+    @Test
+    public void testGetWithNullNamespaceURI() {
+        QNameMap<String> map = new QNameMap<String>();
+        map.put(new QName(null, "name"), "value");
+        assertThat(map.get(null, "name")).isEqualTo("value");
+    }
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void testGetWithNullLocalPart() {
+        new QNameMap<Object>().get("urn:test", null);
+    }
+
+    @Test
+    public void testReplaceExisting() {
+        QNameMap<String> map = new QNameMap<String>();
+        map.put(new QName("urn:test", "name"), "value1");
+        map.put(new QName("urn:test", "name"), "value2");
+        assertThat(map.get("urn:test", "name")).isEqualTo("value2");
+    }
+
+    @Test
+    public void testHashCollision() {
+        QNameMap<String> map = new QNameMap<String>();
+        map.put(new QName("a", "b"), "value1");
+        map.put(new QName("b", "a"), "value2");
+        assertThat(map.get("a", "b")).isEqualTo("value1");
+        assertThat(map.get("b", "a")).isEqualTo("value2");
+    }
+}

Propchange: webservices/axiom/trunk/components/xml-utils/src/test/java/org/apache/axiom/util/xml/QNameMapTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMBuilder.java?rev=1728233&r1=1728232&r2=1728233&view=diff
==============================================================================
--- webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMBuilder.java (original)
+++ webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMBuilder.java Tue Feb  2 22:58:28 2016
@@ -94,7 +94,7 @@ public class FOMBuilder extends StAXOMBu
     @Override
     protected Class<? extends AxiomElement> determineElementType(OMContainer parent,
             int elementLevel, String namespaceURI, String localName) {
-        return fomfactory.determineElementType(parser.getName(), parent);
+        return fomfactory.determineElementType(parent, namespaceURI, localName);
     }
 
     @Override

Modified: webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java?rev=1728233&r1=1728232&r2=1728233&view=diff
==============================================================================
--- webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java (original)
+++ webservices/axiom/trunk/implementations/fom-impl/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java Tue Feb  2 22:58:28 2016
@@ -18,9 +18,7 @@
 package org.apache.abdera.parser.stax;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.activation.MimeType;
 import javax.xml.namespace.QName;
@@ -63,13 +61,14 @@ import org.apache.axiom.om.OMAbstractFac
 import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.impl.common.factory.OMFactoryImpl;
+import org.apache.axiom.util.xml.QNameMap;
 
 @SuppressWarnings( {"unchecked", "deprecation"})
 public class FOMFactory extends OMFactoryImpl implements AbderaFactory, Constants, ExtensionFactory {
-    private static final Map<QName,Class<? extends FOMElement>> elementTypeMap;
+    private static final QNameMap<Class<? extends FOMElement>> elementTypeMap;
     
     static {
-        elementTypeMap = new HashMap<QName,Class<? extends FOMElement>>();
+        elementTypeMap = new QNameMap<Class<? extends FOMElement>>();
         elementTypeMap.put(FEED, FOMFeed.class);
         elementTypeMap.put(SERVICE, FOMService.class);
         elementTypeMap.put(PRE_RFC_SERVICE, FOMService.class);
@@ -509,8 +508,8 @@ public class FOMFactory extends OMFactor
         return createElement(elementType, qname, parent);
     }
 
-    protected Class<? extends FOMElement> determineElementType(QName qname, OMContainer parent) {
-        Class<? extends FOMElement> elementType = elementTypeMap.get(qname);
+    protected Class<? extends FOMElement> determineElementType(OMContainer parent, String namespaceURI, String localName) {
+        Class<? extends FOMElement> elementType = elementTypeMap.get(namespaceURI, localName);
         if (elementType != null) {
             return elementType;
         } else if (parent instanceof ExtensibleElement || parent instanceof Document) {