Author: mrglavas
Date: Wed Mar 16 15:57:25 2011
New Revision: 1082176
URL: http://svn.apache.org/viewvc?rev=1082176&view=rev
Log:
JIRA Issue #1499: http://issues.apache.org/jira/browse/XERCESJ-1499. Reducing
the initial footprint of SymbolHash buckets within a SchemaGrammar from 1,515
to 177 (about 12% of the default size). Implemented a rehash() method on
SymbolHash to grow the maps if they actually become filled.
Modified:
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/SchemaGrammar.java
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/util/SymbolHash.java
Modified:
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/SchemaGrammar.java
URL:
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/SchemaGrammar.java?rev=1082176&r1=1082175&r2=1082176&view=diff
==============================================================================
---
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/SchemaGrammar.java
(original)
+++
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/SchemaGrammar.java
Wed Mar 16 15:57:25 2011
@@ -158,27 +158,29 @@ public class SchemaGrammar implements XS
fGrammarDescription = grammarDesc;
fSymbolTable = symbolTable;
- // REVISIT: do we know the numbers of the following global decls
- // when creating this grammar? If so, we can pass the numbers in,
- // and use that number to initialize the following hashtables.
- fGlobalAttrDecls = new SymbolHash();
- fGlobalAttrGrpDecls = new SymbolHash();
- fGlobalElemDecls = new SymbolHash();
- fGlobalGroupDecls = new SymbolHash();
- fGlobalNotationDecls = new SymbolHash();
- fGlobalIDConstraintDecls = new SymbolHash();
+ // REVISIT: the initial sizes being chosen for each SymbolHash
+ // may not be ideal and could still be tuned. They were chosen
+ // somewhat arbitrarily to reduce the initial footprint of
+ // SymbolHash buckets from 1,515 to 177 (about 12% of the
+ // default size).
+ fGlobalAttrDecls = new SymbolHash(12);
+ fGlobalAttrGrpDecls = new SymbolHash(5);
+ fGlobalElemDecls = new SymbolHash(25);
+ fGlobalGroupDecls = new SymbolHash(5);
+ fGlobalNotationDecls = new SymbolHash(1);
+ fGlobalIDConstraintDecls = new SymbolHash(3);
// Extended tables
- fGlobalAttrDeclsExt = new SymbolHash();
- fGlobalAttrGrpDeclsExt = new SymbolHash();
- fGlobalElemDeclsExt = new SymbolHash();
- fGlobalGroupDeclsExt = new SymbolHash();
- fGlobalNotationDeclsExt = new SymbolHash();
- fGlobalIDConstraintDeclsExt = new SymbolHash();
- fGlobalTypeDeclsExt = new SymbolHash();
+ fGlobalAttrDeclsExt = new SymbolHash(12);
+ fGlobalAttrGrpDeclsExt = new SymbolHash(5);
+ fGlobalElemDeclsExt = new SymbolHash(25);
+ fGlobalGroupDeclsExt = new SymbolHash(5);
+ fGlobalNotationDeclsExt = new SymbolHash(1);
+ fGlobalIDConstraintDeclsExt = new SymbolHash(3);
+ fGlobalTypeDeclsExt = new SymbolHash(25);
// All global elements table
- fAllGlobalElemDecls = new SymbolHash();
+ fAllGlobalElemDecls = new SymbolHash(25);
// if we are parsing S4S, put built-in types in first
// they might get overwritten by the types from S4S, but that's
@@ -187,7 +189,7 @@ public class SchemaGrammar implements XS
fGlobalTypeDecls =
getS4SGrammar(schemaVersion).fGlobalTypeDecls.makeClone();
}
else {
- fGlobalTypeDecls = new SymbolHash();
+ fGlobalTypeDecls = new SymbolHash(25);
}
} // <init>(String, XSDDescription, SymbolTable, short)
Modified:
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java
URL:
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java?rev=1082176&r1=1082175&r2=1082176&view=diff
==============================================================================
---
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java
(original)
+++
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java
Wed Mar 16 15:57:25 2011
@@ -487,13 +487,13 @@ public class XSDHandler {
private String [][] fKeyrefNamespaceContext = new
String[INIT_KEYREF_STACK][1];
// global decls: map from decl name to decl object
- SymbolHash fGlobalAttrDecls = new SymbolHash();
- SymbolHash fGlobalAttrGrpDecls = new SymbolHash();
- SymbolHash fGlobalElemDecls = new SymbolHash();
- SymbolHash fGlobalGroupDecls = new SymbolHash();
- SymbolHash fGlobalNotationDecls = new SymbolHash();
- SymbolHash fGlobalIDConstraintDecls = new SymbolHash();
- SymbolHash fGlobalTypeDecls = new SymbolHash();
+ SymbolHash fGlobalAttrDecls = new SymbolHash(12);
+ SymbolHash fGlobalAttrGrpDecls = new SymbolHash(5);
+ SymbolHash fGlobalElemDecls = new SymbolHash(25);
+ SymbolHash fGlobalGroupDecls = new SymbolHash(5);
+ SymbolHash fGlobalNotationDecls = new SymbolHash(1);
+ SymbolHash fGlobalIDConstraintDecls = new SymbolHash(3);
+ SymbolHash fGlobalTypeDecls = new SymbolHash(25);
// these data members are needed for the deferred traversal
// of referral identity constraints.
Modified:
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/util/SymbolHash.java
URL:
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/util/SymbolHash.java?rev=1082176&r1=1082175&r2=1082176&view=diff
==============================================================================
---
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/util/SymbolHash.java
(original)
+++
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/util/SymbolHash.java
Wed Mar 16 15:57:25 2011
@@ -17,7 +17,6 @@
package org.apache.xerces.util;
-
/**
* This class is an unsynchronized hash table primary used for String
* to Object mapping.
@@ -78,7 +77,8 @@ public class SymbolHash {
* @param value
*/
public void put(Object key, Object value) {
- int bucket = (key.hashCode() & 0x7FFFFFFF) % fTableSize;
+ final int hash = hash(key);
+ int bucket = hash % fTableSize;
Entry entry = search(key, bucket);
// replace old value
@@ -87,6 +87,12 @@ public class SymbolHash {
}
// create new entry
else {
+ if (fNum >= fTableSize) {
+ // Rehash the table if the number of entries
+ // would exceed the number of buckets.
+ rehash();
+ bucket = hash % fTableSize;
+ }
entry = new Entry(key, value, fBuckets[bucket]);
fBuckets[bucket] = entry;
fNum++;
@@ -100,7 +106,7 @@ public class SymbolHash {
* @return the value associated with the given key.
*/
public Object get(Object key) {
- int bucket = (key.hashCode() & 0x7FFFFFFF) % fTableSize;
+ int bucket = hash(key) % fTableSize;
Entry entry = search(key, bucket);
if (entry != null) {
return entry.value;
@@ -156,14 +162,15 @@ public class SymbolHash {
SymbolHash newTable = new SymbolHash(fTableSize);
newTable.fNum = fNum;
for (int i = 0; i < fTableSize; i++) {
- if (fBuckets[i] != null)
+ if (fBuckets[i] != null) {
newTable.fBuckets[i] = fBuckets[i].makeClone();
+ }
}
return newTable;
}
/**
- * Remove all key/value assocaition. This tries to save a bit of GC'ing
+ * Remove all key/value association. This tries to save a bit of GC'ing
* by at least keeping the fBuckets array around.
*/
public void clear() {
@@ -182,6 +189,44 @@ public class SymbolHash {
return null;
}
+ /**
+ * Returns a hashcode value for the specified key.
+ *
+ * @param key The key to hash.
+ */
+ protected int hash(Object key) {
+ return key.hashCode() & 0x7FFFFFFF;
+ }
+
+ /**
+ * Increases the capacity of and internally reorganizes this
+ * SymbolHash, in order to accommodate and access its entries more
+ * efficiently. This method is called automatically when the
+ * number of keys in the SymbolHash exceeds its number of buckets.
+ */
+ protected void rehash() {
+
+ final int oldCapacity = fBuckets.length;
+ final Entry[] oldTable = fBuckets;
+
+ final int newCapacity = (oldCapacity << 1) + 1;
+ final Entry[] newTable = new Entry[newCapacity];
+
+ fBuckets = newTable;
+ fTableSize = fBuckets.length;
+
+ for (int i = oldCapacity; i-- > 0;) {
+ for (Entry old = oldTable[i]; old != null; ) {
+ Entry e = old;
+ old = old.next;
+
+ int index = hash(e.key) % newCapacity;
+ e.next = newTable[index];
+ newTable[index] = e;
+ }
+ }
+ }
+
//
// Classes
//
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]