mmidy 02/05/17 12:38:40
Modified: java/src/org/apache/xml/dtm/ref Tag: XSLTC_DTM
DTMDefaultBase.java DTMDefaultBaseIterators.java
ExpandedNameTable.java
java/src/org/apache/xml/dtm/ref/dom2dtm Tag: XSLTC_DTM
DOM2DTM.java
java/src/org/apache/xml/dtm/ref/sax2dtm Tag: XSLTC_DTM
SAX2DTM.java
Log:
clean up + performance
Revision Changes Path
No revision
No revision
1.28.2.2 +43 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java
Index: DTMDefaultBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java,v
retrieving revision 1.28.2.1
retrieving revision 1.28.2.2
diff -u -r1.28.2.1 -r1.28.2.2
--- DTMDefaultBase.java 17 Apr 2002 18:13:48 -0000 1.28.2.1
+++ DTMDefaultBase.java 17 May 2002 19:38:39 -0000 1.28.2.2
@@ -974,6 +974,27 @@
return makeNodeHandle(firstChild);
}
+
+ /**
+ * Given a node handle, get the handle of the node's first child.
+ * If not yet resolved, waits for more nodes to be added to the document
and
+ * tries again.
+ *
+ * @param nodeHandle int Handle of the node.
+ * @return int DTM node-number of first child, or DTM.NULL to indicate
none exists.
+ */
+ public int getTypedFirstChild(int nodeHandle, int nodeType)
+ {
+
+ int firstChild, eType;
+ for(firstChild = _firstch(makeNodeIdentity(nodeHandle));firstChild !=
DTM.NULL; firstChild = _nextsib(firstChild))
+ {
+ if ((eType =_exptype(firstChild)) == nodeType ||
m_expandedNameTable.getType(eType) == nodeType)
+ //_type(firstChild) == nodeType)
+ return makeNodeHandle(firstChild);
+ }
+ return DTM.NULL;
+ }
/**
* Given a node handle, advance to its last child.
@@ -1065,6 +1086,28 @@
if (nodeHandle == DTM.NULL)
return DTM.NULL;
return makeNodeHandle(_nextsib(makeNodeIdentity(nodeHandle)));
+ }
+
+ /**
+ * Given a node handle, advance to its next sibling.
+ * If not yet resolved, waits for more nodes to be added to the document
and
+ * tries again.
+ * @param nodeHandle int Handle of the node.
+ * @return int Node-number of next sibling,
+ * or DTM.NULL to indicate none exists.
+ */
+ public int getTypedNextSibling(int nodeHandle, int nodeType)
+ {
+ if (nodeHandle == DTM.NULL)
+ return DTM.NULL;
+ int node = makeNodeIdentity(nodeHandle);
+ int eType;
+ while ((node = _nextsib(node)) != DTM.NULL &&
+ ((eType = _exptype(node)) != nodeType &&
+ m_expandedNameTable.getType(eType)!= nodeType));
+ //_type(node) != nodeType));
+
+ return (node == DTM.NULL ? DTM.NULL : makeNodeHandle(node));
}
/**
1.12.2.3 +8 -20
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java
Index: DTMDefaultBaseIterators.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java,v
retrieving revision 1.12.2.2
retrieving revision 1.12.2.3
diff -u -r1.12.2.2 -r1.12.2.3
--- DTMDefaultBaseIterators.java 18 Apr 2002 21:01:42 -0000 1.12.2.2
+++ DTMDefaultBaseIterators.java 17 May 2002 19:38:39 -0000 1.12.2.3
@@ -464,20 +464,11 @@
public int next()
{
- for (int node = (_startNode == DTM.NULL) ? DTM.NULL :(NOTPROCESSED ==
_currentNode)
- ? getFirstChild(_startNode)
- : getNextSibling(_currentNode); node
- != END; node = getNextSibling(node))
- {
- if (getExpandedTypeID(node) == _nodeType || getNodeType(node) ==
_nodeType)
- {
- _currentNode = node;
-
- return returnNode(node);
- }
- }
-
- return END;
+ int node = (_startNode == DTM.NULL) ? DTM.NULL :(NOTPROCESSED ==
_currentNode)
+ ? getTypedFirstChild(_startNode, _nodeType)
+ : getTypedNextSibling(_currentNode, _nodeType);
+ return (node == NULL ? NULL : returnNode(_currentNode = node));
+
}
} // end of TypedChildrenIterator
@@ -886,10 +877,7 @@
public int next()
{
- while ((_currentNode = getNextSibling(_currentNode)) != NULL
- && (getExpandedTypeID(_currentNode) != _nodeType &&
getNodeType(_currentNode) != _nodeType)){}
-
- return (_currentNode == NULL ? NULL : returnNode(_currentNode));
+ return returnNode(_currentNode = getTypedNextSibling(_currentNode,
_nodeType));
}
} // end of TypedFollowingSiblingIterator
@@ -1441,10 +1429,10 @@
_currentNode = m_traverser.next(_startNode, _currentNode);
}
- while (node != NULL
+ while (node != DTM.NULL
&& (getExpandedTypeID(node) != _nodeType && getNodeType(node)
!= _nodeType));
- return (node == NULL ? NULL :returnNode(node));
+ return (node == DTM.NULL ? DTM.NULL :returnNode(node));
}
} // end of TypedFollowingIterator
1.4.2.2 +114 -27
xml-xalan/java/src/org/apache/xml/dtm/ref/ExpandedNameTable.java
Index: ExpandedNameTable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/ExpandedNameTable.java,v
retrieving revision 1.4.2.1
retrieving revision 1.4.2.2
diff -u -r1.4.2.1 -r1.4.2.2
--- ExpandedNameTable.java 17 Apr 2002 18:13:48 -0000 1.4.2.1
+++ ExpandedNameTable.java 17 May 2002 19:38:39 -0000 1.4.2.2
@@ -57,8 +57,10 @@
package org.apache.xml.dtm.ref;
import org.apache.xml.dtm.DTM;
+import org.apache.xml.utils.IntVector;
import java.util.Vector;
+import java.util.Hashtable;
/**
* This is a default implementation of a table that manages mappings from
@@ -87,6 +89,8 @@
private /*static*/ Vector m_extendedTypes;
/** Next available extended type */
+ // %REVIEW% Since this is (should be) always equal
+ // to the length of m_extendedTypes, do we need this?
private int m_nextType;
// These are all the types prerotated, for caller convenience.
@@ -103,7 +107,13 @@
public static final int DOCUMENT_FRAGMENT
=((int)DTM.DOCUMENT_FRAGMENT_NODE) ;
public static final int NOTATION = ((int)DTM.NOTATION_NODE) ;
public static final int NAMESPACE = ((int)DTM.NAMESPACE_NODE) ;
+
+ Hashtable m_hashtable = new Hashtable();
+
+ /** Workspace for lookup. NOT THREAD SAFE!
+ * */
+ ExtendedType hashET=new ExtendedType(-1,"","");
/**
* Create an expanded name table that uses private string pool lookup.
@@ -139,8 +149,16 @@
int i;
for (i = 0; i < DTM.NTYPES; i++)
{
- m_extendedTypes.addElement(new ExtendedType(i, "", "") );
+ ExtendedType newET = new ExtendedType(i, "", "");
+ m_extendedTypes.addElement(newET);
+ m_hashtable.put(newET, new Integer(i));
}
+
+ /* for (i = 0; i < HASHPRIME; i++)
+ {
+ m_hashtable[i] = -1;
+ }*/
+
m_nextType = m_extendedTypes.size();
}
@@ -157,24 +175,54 @@
*/
public int getExpandedTypeID(String namespace, String localName, int type)
{
- /*int nsID = (null != namespace) ?
m_namespaceNames.stringToIndex(namespace) : 0;
- int lnID = m_locNamesPool.stringToIndex(localName);
-
- int expandedTypeID = (type << (BITS_PER_NAMESPACE+BITS_PER_LOCALNAME))
- | (nsID << BITS_PER_LOCALNAME) | lnID;
- return expandedTypeID;
-*/
if (null == namespace)
namespace = "";
- if (null == localName)
+ if (null == localName)
localName = "";
- for (int i = 0; i < m_extendedTypes.size(); i++)
- {
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt(i);
- if( type == etype.nodetype && namespace.equals(etype.namespace) &&
localName.equals(etype.localName))
- return i;
- }
- m_extendedTypes.addElement(new ExtendedType(type, namespace, localName));
+
+
+ // %REVIEW% Linear search is slow. Can we do better?
+ // Some form of hashtable or binary search or...?
+ // The hard part is that we have to hash by multiple
+ // values. Hash by one, test others? Add/XOR their
+ // hash values together to form a combined hash?
+ // (If we're using standard hashtable, that means
+ // defining an object which we'd set these values
+ // into to obtain that hashvalue. See also our string
+ // tables, which implement their own hash lookup, as
+ // a possible alternative approach.)
+ //
+ // %REVIEW% Vectors are slower than arrays. Should we
+ // consider using a reallocated array instead? This
+ // would also avoid the need to cast the returned
+ // object; casting also adds a bit of overhead.
+ // This would cost us when the array has to be expanded
+ // but would make lookup -- our most critical operation
+ // -- faster. That tradeoff's why we went with our own
+ // custom IntVector/SuballocatedIntVector elsewhere
+ // in the DTM code.
+ //
+ // See also comments in the ExtendedType class.
+ //
+ // REMINDER: THIS IS BRAINSTORMING ONLY. I could
+ // be completely off base. Apply common sense and
+ // run benchmark tests, rather than assuming these
+ // ideas make any sense whatsoever, and feel free to
+ // apply better solutons! -- JJK
+
+ // Set our reusable ExpandedType so we can look
+ // it up in the hashtable. Not threadsafe, but
+ // avoids creating a new object until we know
+ // this isn't one we've seen before.
+ hashET.redefine(type,namespace,localName);
+
+ Object eType;
+ if ((eType = m_hashtable.get(hashET)) != null )
+ return ((Integer)eType).intValue();
+
+ ExtendedType newET=new ExtendedType(type, namespace, localName);
+ m_extendedTypes.addElement(newET);
+ m_hashtable.put(newET, new Integer(m_nextType));
return m_nextType++;
}
@@ -193,13 +241,7 @@
return expandedTypeID;
*/
- for (int i = 0; i < m_extendedTypes.size(); i++)
- {
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt(i);
- if( type == etype.nodetype )
- return i;
- }
- return -1; // something's very wrong!
+ return type;
}
/**
@@ -284,20 +326,65 @@
/**
* Private class representing an extended type object
+ *
*/
private class ExtendedType
{
- private int nodetype;
- private String namespace;
- private String localName;
+ protected int nodetype;
+ protected String namespace;
+ protected String localName;
+ protected int hash;
- private ExtendedType (int nodetype, String namespace, String localName)
+ protected ExtendedType (int nodetype, String namespace, String localName)
{
this.nodetype = nodetype;
this.namespace = namespace;
this.localName = localName;
+ this.hash=nodetype+namespace.hashCode()+localName.hashCode();
+ }
+
+ /* This is intended to be used ONLY on the hashET
+ * object. Using it elsewhere will mess up existing
+ * hashtable entries!
+ * */
+ protected void redefine(int nodetype, String namespace, String localName)
+ {
+ this.nodetype = nodetype;
+ this.namespace = namespace;
+ this.localName = localName;
+ this.hash=nodetype+namespace.hashCode()+localName.hashCode();
+ }
+
+ /* Override super method
+ * */
+ public int hashCode()
+ {
+ return hash;
}
+ /* Override super method
+ * */
+ public boolean equals(Object other)
+ {
+ //Usually an optimization, but
+ // won't arise in our usage:
+ //if(other==this) return true;
+ try
+ {
+ ExtendedType et=(ExtendedType)other;
+ return et.nodetype==this.nodetype &&
+ et.localName.equals(this.localName) &&
+ et.namespace.equals(this.namespace);
+ }
+ catch(ClassCastException e)
+ {
+ return false;
+ }
+ catch(NullPointerException e)
+ {
+ return false;
+ }
+ }
}
}
No revision
No revision
1.28.2.3 +33 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java
Index: DOM2DTM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java,v
retrieving revision 1.28.2.2
retrieving revision 1.28.2.3
diff -u -r1.28.2.2 -r1.28.2.3
--- DOM2DTM.java 17 Apr 2002 18:53:55 -0000 1.28.2.2
+++ DOM2DTM.java 17 May 2002 19:38:39 -0000 1.28.2.3
@@ -890,6 +890,39 @@
}
/**
+ * Determine if the string-value of a node is whitespace
+ *
+ * @param nodeHandle The node Handle.
+ *
+ * @return Return true if the given node is whitespace.
+ */
+ public boolean isWhitespace(int nodeHandle)
+ {
+ int type = getNodeType(nodeHandle);
+ Node node = getNode(nodeHandle);
+ if(TEXT_NODE == type || CDATA_SECTION_NODE == type)
+ {
+ // If this is a DTM text node, it may be made of multiple DOM text
+ // nodes -- including navigating into Entity References. DOM2DTM
+ // records the first node in the sequence and requires that we
+ // pick up the others when we retrieve the DTM node's value.
+ //
+ // %REVIEW% DOM Level 3 is expected to add a "whole text"
+ // retrieval method which performs this function for us.
+ FastStringBuffer buf = StringBufferPool.get();
+ while(node!=null)
+ {
+ buf.append(node.getNodeValue());
+ node=logicalNextDOMTextNode(node);
+ }
+ boolean b = buf.isWhitespace(0, buf.length());
+ StringBufferPool.free(buf);
+ return b;
+ }
+ return false;
+ }
+
+ /**
* Retrieve the text content of a DOM subtree, appending it into a
* user-supplied FastStringBuffer object. Note that attributes are
* not considered part of the content of an element.
No revision
No revision
1.28.2.2 +27 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java
Index: SAX2DTM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java,v
retrieving revision 1.28.2.1
retrieving revision 1.28.2.2
diff -u -r1.28.2.1 -r1.28.2.2
--- SAX2DTM.java 17 Apr 2002 18:13:49 -0000 1.28.2.1
+++ SAX2DTM.java 17 May 2002 19:38:40 -0000 1.28.2.2
@@ -1255,6 +1255,33 @@
return m_xstrf.emptystr();
}
+
+ /**
+ * Determine if the string-value of a node is whitespace
+ *
+ * @param nodeHandle The node Handle.
+ *
+ * @return Return true if the given node is whitespace.
+ */
+ public boolean isWhitespace(int nodeHandle)
+ {
+ int identity = makeNodeIdentity(nodeHandle);
+ int type;
+ if(identity==DTM.NULL) // Separate lines because I wanted to breakpoint
it
+ type = DTM.NULL;
+ else
+ type= _type(identity);
+
+ if (isTextType(type))
+ {
+ int dataIndex = _dataOrQName(identity);
+ int offset = m_data.elementAt(dataIndex);
+ int length = m_data.elementAt(dataIndex + 1);
+
+ return m_chars.isWhitespace(offset, length);
+ }
+ return false;
+ }
/**
* Returns the <code>Element</code> whose <code>ID</code> is given by
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]