mkwan 2003/03/05 11:23:04
Modified: java/src/org/apache/xalan/xsltc Tag: XSLTC_DTM DOM.java
java/src/org/apache/xalan/xsltc/compiler Tag: XSLTC_DTM
SyntaxTreeNode.java
java/src/org/apache/xalan/xsltc/compiler/util Tag: XSLTC_DTM
ResultTreeType.java
java/src/org/apache/xalan/xsltc/dom Tag: XSLTC_DTM
DOMAdapter.java DOMImpl.java MultiDOM.java
SAXImpl.java
java/src/org/apache/xalan/xsltc/runtime Tag: XSLTC_DTM
BasisLibrary.java
java/src/org/apache/xalan/xsltc/trax Tag: XSLTC_DTM
XSLTCSource.java
Log:
XSLTC_DTM performance work
Design a new DOM model (SimpleResultTreeImpl) for simple result tree
fragment (RTF). A simple RTF is an RTF which has only one Text node.
It can be generated by a combination of Text, xsl:value-of and xsl:number
instructions. It can also be generated by xsl:if or xsl:choose, as far
as the content of the control body is pure Text. The code to detect whether
an RTF is simple is in SyntaxTreeNode.isSimpleRTF().
Before this change, an RTF is represented by a SAXImpl object. SAXImpl is
a heavy-weight class in that it allocates a lot of array objects for storage.
In the case where the RTF is only one Text node, creating a SAXImpl is just
too expensive.
A SimpleResultTreeImpl has only two nodes, i.e. the root node and the Text
node. All DOM interfaces are overridden to handle this simplified model.
SimpleResultTreeImpl has a few internal iterators, which is designed to
support
the nodeset() extension function.
This change brings a significant improvement to stylesheets that create
a lot of simple RTFs. Some testcases are more than 100% faster after the
change.
Revision Changes Path
No revision
No revision
1.9.10.12 +2 -2 xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java
Index: DOM.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java,v
retrieving revision 1.9.10.11
retrieving revision 1.9.10.12
diff -u -r1.9.10.11 -r1.9.10.12
--- DOM.java 25 Feb 2003 19:14:48 -0000 1.9.10.11
+++ DOM.java 5 Mar 2003 19:22:59 -0000 1.9.10.12
@@ -126,7 +126,7 @@
throws TransletException;
public int getNodeIdent(final int nodehandle);
public int getNodeHandle(final int nodeId);
- public DOM getResultTreeFrag(int initialSize);
+ public DOM getResultTreeFrag(int initialSize, boolean isSimple);
public TransletOutputHandler getOutputDomBuilder();
public int getNSType(int node);
public int getDocument();
No revision
No revision
1.19.2.8 +67 -5
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
Index: SyntaxTreeNode.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java,v
retrieving revision 1.19.2.7
retrieving revision 1.19.2.8
diff -u -r1.19.2.7 -r1.19.2.8
--- SyntaxTreeNode.java 30 Jan 2003 18:41:38 -0000 1.19.2.7
+++ SyntaxTreeNode.java 5 Mar 2003 19:22:59 -0000 1.19.2.8
@@ -539,6 +539,62 @@
}
}
}
+
+ /**
+ * Return true if the node represents a simple RTF.
+ *
+ * A node is a simple RTF if all children only produce Text value.
+ *
+ * @param node A node
+ * @return true if the node content can be considered as a simple RTF.
+ */
+ private boolean isSimpleRTF(SyntaxTreeNode node) {
+
+ Vector contents = node.getContents();
+ for (int i = 0; i < contents.size(); i++) {
+ SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i);
+ if (!isTextElement(item))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return true if the node only produces Text content.
+ *
+ * A node is a Text element if it is Text, xsl:value-of or xsl:number.
+ * It can also be an xsl:if or xsl:choose whose content body are pure
+ * Text.
+ *
+ * @param node A node
+ * @return true if the node of Text type
+ */
+ private boolean isTextElement(SyntaxTreeNode node) {
+ if (node instanceof ValueOf || node instanceof Number
+ || node instanceof Text)
+ {
+ return true;
+ }
+ else if (node instanceof If) {
+ return isSimpleRTF(node);
+ }
+ else if (node instanceof Choose) {
+ Vector contents = node.getContents();
+ for (int i = 0; i < contents.size(); i++) {
+ SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i);
+ if (item instanceof Text ||
+ ((item instanceof When || item instanceof Otherwise)
+ && isSimpleRTF(item)))
+ continue;
+ else
+ return false;
+ }
+ return true;
+ }
+ else
+ return false;
+ }
/**
* Utility method used by parameters and variables to store result trees
@@ -552,6 +608,8 @@
final InstructionList il = methodGen.getInstructionList();
final Stylesheet stylesheet = classGen.getStylesheet();
+ boolean isSimple = isSimpleRTF(this);
+
// Save the current handler base on the stack
il.append(methodGen.loadHandler());
@@ -564,9 +622,10 @@
il.append(methodGen.loadDOM());
int index = cpg.addInterfaceMethodref(DOM_INTF,
"getResultTreeFrag",
- "(I)" + DOM_INTF_SIG);
+ "(IZ)" + DOM_INTF_SIG);
il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
- il.append(new INVOKEINTERFACE(index,2));
+ il.append(new PUSH(cpg, isSimple));
+ il.append(new INVOKEINTERFACE(index,3));
il.append(DUP);
@@ -590,8 +649,11 @@
il.append(methodGen.loadHandler());
il.append(methodGen.endDocument());
- // Check if we need to wrap the DOMImpl object in a DOMAdapter object
- if (!DOM_CLASS.equals(DOM_IMPL_CLASS)) {
+ // Check if we need to wrap the DOMImpl object in a DOMAdapter object.
+ // DOMAdapter is not needed if the RTF is a simple RTF and the nodeset()
+ // function is not used.
+ if ((!isSimple || stylesheet.callsNodeset())
+ && !DOM_CLASS.equals(DOM_IMPL_CLASS)) {
// new org.apache.xalan.xsltc.dom.DOMAdapter(DOMImpl,String[]);
index = cpg.addMethodref(DOM_ADAPTER_CLASS,
"<init>",
No revision
No revision
1.10.6.8 +4 -3
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ResultTreeType.java
Index: ResultTreeType.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/ResultTreeType.java,v
retrieving revision 1.10.6.7
retrieving revision 1.10.6.8
diff -u -r1.10.6.7 -r1.10.6.8
--- ResultTreeType.java 30 Jan 2003 18:41:45 -0000 1.10.6.7
+++ ResultTreeType.java 5 Mar 2003 19:22:59 -0000 1.10.6.8
@@ -280,9 +280,10 @@
il.append(methodGen.loadDOM());
int index = cpg.addInterfaceMethodref(DOM_INTF,
"getResultTreeFrag",
- "(I)" + DOM_INTF_SIG);
+ "(IZ)" + DOM_INTF_SIG);
il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
- il.append(new INVOKEINTERFACE(index,2));
+ il.append(new PUSH(cpg, false));
+ il.append(new INVOKEINTERFACE(index,3));
il.append(DUP);
// Store new DOM into a local variable
No revision
No revision
1.11.10.15 +18 -9
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
Index: DOMAdapter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v
retrieving revision 1.11.10.14
retrieving revision 1.11.10.15
diff -u -r1.11.10.14 -r1.11.10.15
--- DOMAdapter.java 25 Feb 2003 19:14:49 -0000 1.11.10.14
+++ DOMAdapter.java 5 Mar 2003 19:22:59 -0000 1.11.10.15
@@ -101,7 +101,7 @@
String[] namespaceArray) {
if (dom instanceof DOMImpl) {
_domImpl = (DOMImpl) dom;
- } else {
+ } else if (dom instanceof SAXImpl){
_saxImpl = (SAXImpl) dom;
}
@@ -116,7 +116,8 @@
}
public DOM getDOMImpl() {
- return (_domImpl != null) ? (DOM)_domImpl : (DOM)_saxImpl;
+ //return (_domImpl != null) ? (DOM)_domImpl : (DOM)_saxImpl;
+ return _dom;
}
private short[] getMapping() {
@@ -134,7 +135,7 @@
if (_reverse == null) {
if (_domImpl != null) {
_reverse = _domImpl.getReverseMapping(_namesArray);
- } else {
+ } else if (_saxImpl != null){
_reverse = _saxImpl.getReverseMapping(_namesArray);
}
}
@@ -198,7 +199,9 @@
public DTMAxisIterator getTypedChildren(final int type) {
final int[] reverse = getReverse();
- DTMAxisIterator iterator = _dom.getTypedChildren(reverse[type]);
+ DTMAxisIterator iterator = (reverse != null)
+ ? _dom.getTypedChildren(reverse[type])
+ : _dom.getTypedChildren(type);
/*
if (_filter != null && reverse[type] == DTM.TEXT_NODE) {
if (_domImpl != null) {
@@ -242,7 +245,9 @@
iterator = _dom.getTypedAxisIterator(axis, NSReverse[type]);
}
} else {
- iterator = _dom.getTypedAxisIterator(axis, reverse[type]);
+ iterator = (reverse != null)
+ ? _dom.getTypedAxisIterator(axis, reverse[type])
+ : _dom.getTypedAxisIterator(axis, type);
}
/*
@@ -403,15 +408,19 @@
public String getDocumentURI(int node)
{
+ /*
if (_domImpl != null)
return _domImpl.getDocumentURI();
else
return _saxImpl.getDocumentURI();
+ */
+ return _dom.getDocumentURI(node);
}
public int getDocument()
{
- return(((DTMDefaultBase)_dom).getDocument());
+ //return(((DTMDefaultBase)_dom).getDocument());
+ return _dom.getDocument();
}
public boolean isElement(final int node)
@@ -437,9 +446,9 @@
/**
* Return a instance of a DOM class to be used as an RTF
*/
- public DOM getResultTreeFrag(int initSize)
+ public DOM getResultTreeFrag(int initSize, boolean isSimple)
{
- return _dom.getResultTreeFrag(initSize);
+ return _dom.getResultTreeFrag(initSize, isSimple);
}
/**
1.68.2.26 +2 -2
xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
Index: DOMImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
retrieving revision 1.68.2.25
retrieving revision 1.68.2.26
diff -u -r1.68.2.25 -r1.68.2.26
--- DOMImpl.java 3 Mar 2003 15:51:38 -0000 1.68.2.25
+++ DOMImpl.java 5 Mar 2003 19:22:59 -0000 1.68.2.26
@@ -1839,7 +1839,7 @@
/**
* Return a instance of a DOM class to be used as an RTF
*/
- public DOM getResultTreeFrag(int initSize)
+ public DOM getResultTreeFrag(int initSize, boolean isSimple)
{
return (SAXImpl) ((XSLTCDTMManager)m_mgr).getDTM(null, true,
m_wsfilter,
true, false, false,
1.16.10.14 +21 -10
xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java
Index: MultiDOM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/MultiDOM.java,v
retrieving revision 1.16.10.13
retrieving revision 1.16.10.14
diff -u -r1.16.10.13 -r1.16.10.14
--- MultiDOM.java 25 Feb 2003 19:14:50 -0000 1.16.10.13
+++ MultiDOM.java 5 Mar 2003 19:23:00 -0000 1.16.10.14
@@ -291,16 +291,27 @@
// This method only has a function in DOM adapters
}
- public int addDOMAdapter(DOMAdapter dom) {
- return addDOMAdapter(dom, true);
+ public int addDOMAdapter(DOMAdapter adapter) {
+ return addDOMAdapter(adapter, true);
}
- private int addDOMAdapter(DOMAdapter dom, boolean indexByURI) {
+ private int addDOMAdapter(DOMAdapter adapter, boolean indexByURI) {
// Add the DOM adapter to the array of DOMs
+ DOM dom = adapter.getDOMImpl();
+
+ DTMManager dtmManager = null;
+ if (dom instanceof DTMDefaultBase)
+ dtmManager = ((DTMDefaultBase)dom).m_mgr;
+ else if (dom instanceof SimpleResultTreeImpl)
+ dtmManager = ((SimpleResultTreeImpl)dom).getDTMManager();
+
+ /*
DTMManager dtmManager =
((DTMDefaultBase)((DOMAdapter)dom).getDOMImpl()).m_mgr;
+ */
+
final int domNo =
- dtmManager.getDTMIdentity((DTM)((DOMAdapter)dom).getDOMImpl())
+ dtmManager.getDTMIdentity((DTM)dom)
>>> DTMManager.IDENT_DTM_NODE_BITS;
if (domNo >= _size) {
@@ -313,16 +324,16 @@
System.arraycopy(_adapters, 0, newArray, 0, oldSize);
_adapters = newArray;
}
- _adapters[domNo] = dom;
+ _adapters[domNo] = adapter;
// Store reference to document (URI) in hashtable
if (indexByURI) {
- String uri = dom.getDocumentURI(0);
+ String uri = adapter.getDocumentURI(0);
_documents.put(uri, new Integer(domNo));
}
// Store mask in DOMAdapter
- dom.setMultiDOMMask(domNo << 24);
+ adapter.setMultiDOMMask(domNo << 24);
return (domNo << 24);
}
@@ -588,9 +599,9 @@
return _adapters[nodeId>>>24].getNodeHandle(nodeId & CLR);
}
- public DOM getResultTreeFrag(int initSize)
+ public DOM getResultTreeFrag(int initSize, boolean isSimple)
{
- return _adapters[0].getResultTreeFrag(initSize);
+ return _adapters[0].getResultTreeFrag(initSize, isSimple);
}
public DOM getMain()
1.1.2.39 +19 -7
xml-xalan/java/src/org/apache/xalan/xsltc/dom/Attic/SAXImpl.java
Index: SAXImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/Attic/SAXImpl.java,v
retrieving revision 1.1.2.38
retrieving revision 1.1.2.39
diff -u -r1.1.2.38 -r1.1.2.39
--- SAXImpl.java 3 Mar 2003 15:51:39 -0000 1.1.2.38
+++ SAXImpl.java 5 Mar 2003 19:23:00 -0000 1.1.2.39
@@ -172,6 +172,9 @@
// Object used to map TransletOutputHandler events to SAX events
private CH2TOH _ch2toh = new CH2TOH();
+
+ // The DTMManager
+ private XSLTCDTMManager _dtmManager;
// Support for access/navigation through org.w3c.dom API
private Node[] _nodes;
@@ -1037,7 +1040,7 @@
/**
* Construct a SAXImpl object using the default block size.
*/
- public SAXImpl(DTMManager mgr, Source saxSource,
+ public SAXImpl(XSLTCDTMManager mgr, Source saxSource,
int dtmIdentity, DTMWSFilter whiteSpaceFilter,
XMLStringFactory xstringfactory,
boolean doIndexing, boolean buildIdIndex)
@@ -1049,7 +1052,7 @@
/**
* Construct a SAXImpl object using the given block size.
*/
- public SAXImpl(DTMManager mgr, Source saxSource,
+ public SAXImpl(XSLTCDTMManager mgr, Source saxSource,
int dtmIdentity, DTMWSFilter whiteSpaceFilter,
XMLStringFactory xstringfactory,
boolean doIndexing, int blocksize,
@@ -1058,6 +1061,7 @@
super(mgr, saxSource, dtmIdentity, whiteSpaceFilter, xstringfactory,
doIndexing, blocksize, false, buildIdIndex);
+ _dtmManager = mgr;
_size = blocksize;
// Use a smaller size for the space stack if the blocksize is small
@@ -2118,11 +2122,19 @@
/**
* Return a instance of a DOM class to be used as an RTF
*/
- public DOM getResultTreeFrag(int initSize)
+ public DOM getResultTreeFrag(int initSize, boolean isSimple)
{
- return (SAXImpl) ((XSLTCDTMManager)m_mgr).getDTM(null, true, m_wsfilter,
- true, false, false,
- initSize,
m_buildIdIndex);
+ if (isSimple) {
+ int dtmPos = _dtmManager.getFirstFreeDTMID();
+ SimpleResultTreeImpl rtf = new SimpleResultTreeImpl(_dtmManager,
+ dtmPos <<
DTMManager.IDENT_DTM_NODE_BITS);
+ _dtmManager.addDTM(rtf, dtmPos, 0);
+ return rtf;
+ }
+ else
+ return (SAXImpl) _dtmManager.getDTM(null, true, m_wsfilter,
+ true, false, false,
+ initSize, m_buildIdIndex);
}
/**
No revision
No revision
1.35.2.18 +8 -5
xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
Index: BasisLibrary.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
retrieving revision 1.35.2.17
retrieving revision 1.35.2.18
diff -u -r1.35.2.17 -r1.35.2.18
--- BasisLibrary.java 3 Mar 2003 15:51:41 -0000 1.35.2.17
+++ BasisLibrary.java 5 Mar 2003 19:23:03 -0000 1.35.2.18
@@ -484,7 +484,7 @@
return "boolean";
else if (obj instanceof Number)
return "number";
- else if (obj instanceof DOMAdapter)
+ else if (obj instanceof DOM)
return "RTF";
else if (obj instanceof DTMAxisIterator)
return "node-set";
@@ -497,8 +497,9 @@
*/
public static DTMAxisIterator nodesetF(Object obj) {
if (obj instanceof DOM) {
- final DOMAdapter adapter = (DOMAdapter) obj;
- return new SingletonIterator(adapter.getDocument(), true);
+ //final DOMAdapter adapter = (DOMAdapter) obj;
+ final DOM dom = (DOM)obj;
+ return new SingletonIterator(dom.getDocument(), true);
}
else if (obj instanceof DTMAxisIterator) {
return (DTMAxisIterator) obj;
@@ -1240,7 +1241,9 @@
dom.copy(((Node) obj).node, handler);
}
else if (obj instanceof DOM) {
-
((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(),
handler);
+
//((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(),
handler);
+ DOM newDom = (DOM)obj;
+ newDom.copy(newDom.getDocument(), handler);
}
else {
String string = obj.toString(); // or call stringF()
No revision
No revision
1.3.10.8 +7 -7
xml-xalan/java/src/org/apache/xalan/xsltc/trax/XSLTCSource.java
Index: XSLTCSource.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/trax/XSLTCSource.java,v
retrieving revision 1.3.10.7
retrieving revision 1.3.10.8
diff -u -r1.3.10.7 -r1.3.10.8
--- XSLTCSource.java 3 Mar 2003 15:51:41 -0000 1.3.10.7
+++ XSLTCSource.java 5 Mar 2003 19:23:04 -0000 1.3.10.8
@@ -99,13 +99,13 @@
*/
public XSLTCSource(int size)
{
- DTMManager dtmManager =
+ XSLTCDTMManager dtmManager =
XSLTCDTMManager.newInstance();
- int dtmPos = ((DTMManagerDefault)dtmManager).getFirstFreeDTMID();
+ int dtmPos = dtmManager.getFirstFreeDTMID();
int documentID = dtmPos << DTMManager.IDENT_DTM_NODE_BITS;
_dom = (DOM)new SAXImpl(dtmManager, this, documentID, null,
null, false, size, true);
- ((DTMManagerDefault)dtmManager).addDTM((DTM)_dom, dtmPos);
+ dtmManager.addDTM((DTM)_dom, dtmPos);
}
/**
@@ -113,13 +113,13 @@
*/
public XSLTCSource()
{
- DTMManager dtmManager =
+ XSLTCDTMManager dtmManager =
XSLTCDTMManager.newInstance();
- int dtmPos = ((DTMManagerDefault)dtmManager).getFirstFreeDTMID();
+ int dtmPos = dtmManager.getFirstFreeDTMID();
int documentID = dtmPos << DTMManager.IDENT_DTM_NODE_BITS;
_dom = (DOM)new SAXImpl(dtmManager, this, documentID, null,
null, false, true);
- ((DTMManagerDefault)dtmManager).addDTM((DTM)_dom, dtmPos);
+ dtmManager.addDTM((DTM)_dom, dtmPos);
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]