jkesselm 01/07/20 11:48:11
Modified: java/src/org/apache/xalan/lib/sql SQLDocument.java
java/src/org/apache/xalan/transformer
TransformerHandlerImpl.java
java/src/org/apache/xml/dtm/ref DTMDefaultBase.java
DTMDocumentImpl.java DTMManagerDefault.java
IncrementalSAXSource.java
IncrementalSAXSource_Filter.java
IncrementalSAXSource_Xerces.java
java/src/org/apache/xml/dtm/ref/dom2dtm DOM2DTM.java
java/src/org/apache/xml/dtm/ref/sax2dtm SAX2DTM.java
java/src/org/apache/xml/utils SuballocatedIntVector.java
Log:
IncrementalSAXSource replaces CoroutineSAXParser -- simpler API,
hence less risk of programming errors introducing timing windows.
I hope.
A few performance-related tweaks are also included in this check-in.
Only very minor gains are expected.
Revision Changes Path
1.10 +5 -1
xml-xalan/java/src/org/apache/xalan/lib/sql/SQLDocument.java
Index: SQLDocument.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/SQLDocument.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- SQLDocument.java 2001/07/20 06:26:31 1.9
+++ SQLDocument.java 2001/07/20 18:48:10 1.10
@@ -1477,6 +1477,7 @@
super.setShouldStripWhitespace( parm1);
}
+
protected void ensureSizeOfIndex(int parm1, int parm2)
{
if (DEBUG) System.out.println("ensureSizeOfIndex("+parm1+","+parm2+")");
@@ -1486,7 +1487,10 @@
protected void ensureSize(int parm1)
{
if (DEBUG) System.out.println("ensureSize("+parm1+")");
- super.ensureSize( parm1);
+
+ // IntVectors in DTMDefaultBase are now self-sizing, and ensureSize()
+ // is being dropped.
+ //super.ensureSize( parm1);
}
public String getDocumentEncoding(int parm1)
1.10 +13 -90
xml-xalan/java/src/org/apache/xalan/transformer/TransformerHandlerImpl.java
Index: TransformerHandlerImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerHandlerImpl.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TransformerHandlerImpl.java 2001/07/13 19:09:18 1.9
+++ TransformerHandlerImpl.java 2001/07/20 18:48:10 1.10
@@ -84,10 +84,8 @@
import org.apache.xpath.XPathContext;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMManager;
-
-// Bad, bad, we should work towards having to have these referenced here.
-import org.apache.xml.dtm.ref.CoroutineManager;
-import org.apache.xml.dtm.ref.CoroutineSAXParser;
+import org.apache.xml.dtm.ref.IncrementalSAXSource;
+import org.apache.xml.dtm.ref.IncrementalSAXSource_Filter;
import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;
/**
@@ -141,7 +139,6 @@
*/
protected void clearCoRoutine()
{
-
clearCoRoutine(null);
}
@@ -157,37 +154,12 @@
System.out.println("In clearCoRoutine...");
SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);
if(null != m_contentHandler
- && m_contentHandler instanceof CoroutineSAXParser)
+ && m_contentHandler instanceof IncrementalSAXSource_Filter)
{
- CoroutineSAXParser sp = (CoroutineSAXParser)m_contentHandler;
-
- if(m_insideParse)
- {
- // %REVIEW% Joe needs to review this.
- // If we are in a condition where the parser threw an exception,
- // we have to make sure that doMore doesn't call to wait on
- // the other thread, so in this case we first clear the parser
- // thread from the CoRoutine manager.
- if(null != ex)
- {
- sp.getCoroutineManager().co_exit(sp.getParserCoroutineID());
- sp.doMore(false, sax2dtm.getAppCoroutineID());
-
- // Actually, I think we're always incremental here...
- if(DTMManager.getIncremental())
- {
- try
- {
- m_transformer.waitTransformThread();
- }
- catch(SAXException se){}
- }
- }
- else
- {
- sp.doMore(false, sax2dtm.getAppCoroutineID());
- }
- }
+ IncrementalSAXSource_Filter sp =
+ (IncrementalSAXSource_Filter)m_contentHandler;
+ // This should now be all that's needed.
+ sp.deliverMoreNodes(false);
}
sax2dtm.clearCoRoutine(true);
@@ -202,57 +174,6 @@
}
}
- /**
- * Wait for initial events. This has to be called by the secondary thread
- * upon startup.
- */
- protected void waitForInitialEvents()
- {
- m_hasStarted = true;
-
- if(m_dtm instanceof SAX2DTM)
- {
- if(DEBUG)
- System.out.println("In clearCoRoutine...");
- SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);
- if(null != m_contentHandler
- && m_contentHandler instanceof CoroutineSAXParser)
- {
- CoroutineSAXParser sp = (CoroutineSAXParser)m_contentHandler;
- sp.doMore(true, sax2dtm.getAppCoroutineID());
- }
- }
- }
-
- /**
- * Call co_entry_pause on the CoroutineSAXParser.
- */
- protected void pauseForTransformThreadStartup()
- {
-
- if(m_dtm instanceof SAX2DTM)
- {
- if(DEBUG)
- System.out.println("In pauseForTransformThreadStartup...");
- SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);
- if(null != m_contentHandler
- && m_contentHandler instanceof CoroutineSAXParser)
- {
- CoroutineSAXParser sp = (CoroutineSAXParser)m_contentHandler;
- try
- {
- sp.getCoroutineManager().co_entry_pause(sp.getParserCoroutineID());
- }
- catch(java.lang.NoSuchMethodException nsme)
- {
- // ignore.
- }
- }
- }
- }
-
-
-
////////////////////////////////////////////////////////////////////
// Implementation of javax.xml.transform.sax.TransformerHandler.
////////////////////////////////////////////////////////////////////
@@ -446,8 +367,6 @@
if (m_contentHandler != null)
{
- m_contentHandler.startDocument();
-
//m_transformer.setTransformThread(listener);
if(DTMManager.getIncremental())
{
@@ -458,11 +377,15 @@
// runTransformThread is equivalent with the 2.0.1 code,
// except that the Thread may come from a pool.
m_transformer.runTransformThread( cpriority );
- pauseForTransformThreadStartup();
if(false == m_hasStarted)
System.err.println("Transform thread has still not started after
pauseForTransformThreadStartup!");
}
-
+
+ // This is now done _last_, because IncrementalSAXSource_Filter
+ // will immediately go into a "wait until events are requested"
+ // pause. I believe that will close our timing window.
+ // %REVIEW%
+ m_contentHandler.startDocument();
}
//listener.setDaemon(false);
1.12 +44 -48
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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- DTMDefaultBase.java 2001/06/29 21:45:31 1.11
+++ DTMDefaultBase.java 2001/07/20 18:48:10 1.12
@@ -87,6 +87,12 @@
*/
public abstract class DTMDefaultBase implements DTM
{
+ /** %OPT% %REVIEW% When true, don't build the m_level array;
+ * instead, support _level()/getLevel() by counting upward to the
+ * root. This is exposed because SAX2DTM and DOM2DTM should
+ * respond to it. */
+ protected static final boolean DISABLE_PRECALC_LEVEL=true;
+
/**
* The number of nodes, which is also used to determine the next
* node index.
@@ -98,14 +104,7 @@
/** levels deep, one array element for each node.
*
- * %REVIEW% Are 256 levels really enough? (Yes for most docs, but maybe not
- * for something deeply structured.) Should this be shorts instead? Or
give up
- * and go back to int?
- *
- * %REVIEW% We may be concluding that, given some of the other changes DTM
- * and the new traversal code have bought us, level no longer needs to be
- * tracked at all. Keep it for now because it's useful as a DTM diagnostic,
- * but consider phasing it out.
+ * %REVIEW% Used only when DISABLE_PRECALC_LEVEL is false!
*/
protected SuballocatedByteVector m_level;
@@ -217,11 +216,14 @@
}
m_exptype = new SuballocatedIntVector(m_initialblocksize);
- m_level = new SuballocatedByteVector(m_initialblocksize);
m_firstch = new SuballocatedIntVector(m_initialblocksize);
m_nextsib = new SuballocatedIntVector(m_initialblocksize);
m_prevsib = new SuballocatedIntVector(m_initialblocksize);
m_parent = new SuballocatedIntVector(m_initialblocksize);
+
+ if(!DISABLE_PRECALC_LEVEL)
+ m_level = new SuballocatedByteVector(m_initialblocksize);
+
m_mgr = mgr;
m_documentBaseURI = (null != source) ? source.getSystemId() : null;
m_dtmIdent = dtmIdentity;
@@ -441,17 +443,17 @@
/** Stateless axis traversers, lazely built. */
protected DTMAxisTraverser[] m_traversers;
- /**
- * Ensure that the size of the information arrays can hold another entry
- * at the given index.
- *
- * @param index On exit from this function, the information arrays sizes
must be
- * at least index+1.
- */
- protected void ensureSize(int index)
- {
- // We've cut over to Suballocated*Vector, which are self-sizing.
- }
+// /**
+// * Ensure that the size of the information arrays can hold another
entry
+// * at the given index.
+// *
+// * @param index On exit from this function, the information arrays
sizes must be
+// * at least index+1.
+// */
+// protected void ensureSize(int index)
+// {
+// // We've cut over to Suballocated*Vector, which are self-sizing.
+// }
/**
* Get the simple type ID for the given node identity.
@@ -480,22 +482,16 @@
*/
protected int _exptype(int identity)
{
-
- if (identity < m_size)
- return m_exptype.elementAt(identity);
-
- // Check to see if the information requested has been processed, and,
- // if not, advance the iterator until we the information has been
- // processed.
- while (true)
+ // Reorganized test and loop into single flow
+ // Tiny performance improvement, saves a few bytes of code, clearer.
+ // %OPT% Other internal getters could be treated simliarly
+ while (identity>=m_size)
{
- boolean isMore = nextNode();
-
- if (identity >= m_size && !isMore)
+ if (!nextNode() && identity >= m_size)
return NULL;
- else if (identity < m_size)
- return m_exptype.elementAt(identity);
}
+ return m_exptype.elementAt(identity);
+
}
/**
@@ -507,22 +503,24 @@
*/
protected int _level(int identity)
{
-
- if (identity < m_size)
- return m_level.elementAt(identity);
-
- // Check to see if the information requested has been processed, and,
- // if not, advance the iterator until we the information has been
- // processed.
- while (true)
+ while (identity>=m_size)
{
boolean isMore = nextNode();
-
- if (identity >= m_size && !isMore)
+ if (!isMore && identity >= m_size)
return NULL;
- else if (identity < m_size)
- return m_level.elementAt(identity);
}
+
+ if(DISABLE_PRECALC_LEVEL)
+ {
+ int i=0;
+ while(NULL != (identity=_parent(identity)))
+ ++i;
+ return i;
+ }
+ else
+ {
+ return m_level.elementAt(identity);
+ }
}
/**
@@ -1524,10 +1522,8 @@
*/
public short getLevel(int nodeHandle)
{
-
- int identity = nodeHandle & m_mask;
-
// Apparently, the axis walker stuff requires levels to count from 1.
+ int identity = nodeHandle & m_mask;
return (short) (_level(identity) + 1);
}
1.4 +22 -44
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDocumentImpl.java
Index: DTMDocumentImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDocumentImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DTMDocumentImpl.java 2001/07/11 04:00:13 1.3
+++ DTMDocumentImpl.java 2001/07/20 18:48:11 1.4
@@ -145,22 +145,10 @@
* fallback, but that has all the known problems with multithreading
* on multiprocessors and we Don't Want to Go There.
*
- * @see setCoroutineParser
+ * @see setIncrementalSAXSource
*/
- private CoroutineParser m_coroutineParser=null;
+ private IncrementalSAXSource m_incrSAXSource=null;
- /** If we're building the model incrementally on demand, we need to
- * be able to tell the source who to return the data to.
- *
- * Note that if this has not been set, and you attempt to read ahead
- * of the current build point, we'll probably throw a MethodNotFound
- * exception. We could try to wait-and-retry instead, as a very poor
- * fallback, but that has all the known problems with multithreading
- * on multiprocessors and we Don't Want to Go There.
- *
- * @see setCoroutineParser
- */
- private int m_appCoroutineID=-1;
// ========= DTM data structure declarations. ==============
@@ -215,40 +203,30 @@
m_xsf = xstringfactory;
}
- /** Bind a CoroutineParser to this DTM. If we discover we need nodes
+ /** Bind a IncrementalSAXSource to this DTM. If we discover we need nodes
* that have not yet been built, we will ask this object to send us more
* events, and it will manage interactions with its data sources.
*
- * Note that we do not actually build the CoroutineParser, since we don't
+ * Note that we do not actually build the IncrementalSAXSource, since we
don't
* know what source it's reading from, what thread that source will run in,
* or when it will run.
*
- * @param coroutineParser The parser that we want to recieve events from
+ * @param source The IncrementalSAXSource that we want to recieve events
from
* on demand.
*/
- public void setCoroutineParser(CoroutineParser coroutineParser)
+ public void setIncrementalSAXSource(IncrementalSAXSource source)
{
- // Establish coroutine link so we can request more data
- //
- // Note: It's possible that some versions of CoroutineParser may
- // not actually use a CoroutineManager, and hence may not require
- // that we obtain an Application Coroutine ID. (This relies on the
- // coroutine transaction details having been encapsulated in the
- // CoroutineParser.do...() methods.)
- m_coroutineParser=coroutineParser;
- CoroutineManager cm=coroutineParser.getCoroutineManager();
- if(cm!=null)
- m_appCoroutineID=cm.co_joinCoroutineSet(-1);
+ m_incrSAXSource=source;
// Establish SAX-stream link so we can receive the requested data
- coroutineParser.setContentHandler(this);
- coroutineParser.setLexHandler(this);
+ source.setContentHandler(this);
+ source.setLexicalHandler(this);
- // Are the following really needed? coroutineParser doesn't yet
+ // Are the following really needed? IncrementalSAXSource doesn't yet
// support them, and they're mostly no-ops here...
- //coroutineParser.setErrorHandler(this);
- //coroutineParser.setDTDHandler(this);
- //coroutineParser.setDeclHandler(this);
+ //source.setErrorHandler(this);
+ //source.setDTDHandler(this);
+ //source.setDeclHandler(this);
}
/**
@@ -375,13 +353,13 @@
*
* @return null if this model doesn't respond to SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrementalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
* */
public org.xml.sax.ContentHandler getContentHandler()
{
- if (m_coroutineParser instanceof CoroutineSAXParser)
- return (ContentHandler) m_coroutineParser;
+ if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
+ return (ContentHandler) m_incrSAXSource;
else
return this;
}
@@ -393,14 +371,14 @@
*
* @return null if this model doesn't respond to lexical SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrementalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
*/
public LexicalHandler getLexicalHandler()
{
- if (m_coroutineParser instanceof CoroutineSAXParser)
- return (LexicalHandler) m_coroutineParser;
+ if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
+ return (LexicalHandler) m_incrSAXSource;
else
return this;
}
@@ -450,13 +428,13 @@
}
/** @return true iff we're building this model incrementally (eg
- * we're partnered with a CoroutineParser) and thus require that the
+ * we're partnered with a IncrementalSAXSource) and thus require that the
* transformation and the parse run simultaneously. Guidance to the
* DTMManager.
* */
public boolean needsTwoThreads()
{
- return null!=m_coroutineParser;
+ return null!=m_incrSAXSource;
}
//================================================================
@@ -1214,7 +1192,7 @@
* additional logic for the public view. If we're rewriting
* for XPath emulation, that test must be done here.
*
- * %TBD% CODE INTERACTION WITH COROUTINE PARSE - If not yet
+ * %TBD% CODE INTERACTION WITH INCREMENTAL PARSE - If not yet
* resolved, should wait for more nodes to be added to the document
* and tries again.
*
1.17 +19 -51
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java
Index: DTMManagerDefault.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DTMManagerDefault.java 2001/07/03 15:47:18 1.16
+++ DTMManagerDefault.java 2001/07/20 18:48:11 1.17
@@ -251,28 +251,19 @@
incremental = true; // No matter what. %REVIEW%
// If the reader is null, but they still requested an incremental
build,
- // then we still want to set up the CoRoutine stuff.
+ // then we still want to set up the IncrementalSAXSource stuff.
if (this.m_incremental && incremental /* || ((null == reader) &&
incremental) */)
{
+ IncrementalSAXSource coParser=null;
- // Create a CoroutineManager to manage the coordination between
the
- // parser and the transformation. This will "throttle" between
- // the parser and the calling application.
- CoroutineManager coroutineManager = new CoroutineManager();
-
- // Create an CoRoutine ID for the transformation.
- int appCoroutine = coroutineManager.co_joinCoroutineSet(-1);
- CoroutineParser coParser=null;
-
if (haveXercesParser)
{
- // CoroutineSAXParser_Xerces to avoid threading.
- // System.out.println("Using CoroutineSAXParser_Xerces to avoid
threading");
+ // IncrementalSAXSource_Xerces to avoid threading.
+ // System.out.println("Using IncrementalSAXSource_Xerces to
avoid threading");
try {
// should be ok, it's in the same package - no need for thread
class loader
- Class c=Class.forName(
"org.apache.xml.dtm.ref.CoroutineSAXParser_Xerces" );
- coParser=(CoroutineParser)c.newInstance();
- coParser.init( coroutineManager, appCoroutine, reader );
+ Class c=Class.forName(
"org.apache.xml.dtm.ref.IncrementalSAXSource_Xerces" );
+ coParser=(IncrementalSAXSource)c.newInstance();
} catch( Exception ex ) {
ex.printStackTrace();
coParser=null;
@@ -280,20 +271,20 @@
}
if( coParser==null ) {
- // Create a CoroutineSAXParser that will run on the secondary
thread.
+ // Create a IncrementalSAXSource that will run on the secondary
thread.
if (null == reader)
- coParser = new CoroutineSAXParser(coroutineManager,
- appCoroutine);
+ coParser = new IncrementalSAXSource_Filter();
else
- coParser = new CoroutineSAXParser(coroutineManager,
- appCoroutine, reader);
+ {
+ IncrementalSAXSource_Filter filter=new
IncrementalSAXSource_Filter();
+ filter.setXMLReader(reader);
+ coParser=filter;
+ }
+
}
-
- // Have the DTM set itself up as the CoroutineSAXParser's listener.
- dtm.setCoroutineParser(coParser, appCoroutine);
- // Get the parser's CoRoutine ID.
- int parserCoroutine = coParser.getParserCoroutineID();
+ // Have the DTM set itself up as the IncrementalSAXSource's
listener.
+ dtm.setIncrementalSAXSource(coParser);
if (null == xmlSource)
{
@@ -302,39 +293,19 @@
return dtm;
}
- // System.out.println("parserCoroutine (mgr): "+parserCoroutine);
- // %TBD% It's probably OK to have these bypass the CoRoutine
stuff??
- // Or maybe not?
- // ... Depends on how broken will things get if they occur at the
same
- // time that someone is trying to read the DTM model. I'd suggest
that
- // we instead extend CoroutineParser to handle these, and let it
- // pass the registration through to the reader if that's the Right
Thng
reader.setDTDHandler(dtm);
reader.setErrorHandler(dtm);
try
{
-
- // %REVIEW% Consider making coParser just be a throttling filter
- Object gotMore = coParser.doParse(xmlSource, appCoroutine);
-
- if (gotMore instanceof Exception)
- {
- dtm.clearCoRoutine();
- throw ((Exception) gotMore);
- }
- else if (gotMore != Boolean.TRUE)
- {
-
- // %REVIEW% Consider having coParser self-terminate at end of
file.
- dtm.clearCoRoutine();
- }
+ // Launch parsing coroutine. Launches a second thread,
+ // if we're using IncrementalSAXSource.filter().
+ coParser.startParse(xmlSource);
}
catch (RuntimeException re)
{
- // coroutineManager.co_exit(appCoroutine);
dtm.clearCoRoutine();
throw re;
@@ -342,7 +313,6 @@
catch (Exception e)
{
- // coroutineManager.co_exit(appCoroutine);
dtm.clearCoRoutine();
throw new org.apache.xml.utils.WrappedRuntimeException(e);
@@ -377,7 +347,6 @@
catch (RuntimeException re)
{
- // coroutineManager.co_exit(appCoroutine);
dtm.clearCoRoutine();
throw re;
@@ -385,7 +354,6 @@
catch (Exception e)
{
- // coroutineManager.co_exit(appCoroutine);
dtm.clearCoRoutine();
throw new org.apache.xml.utils.WrappedRuntimeException(e);
1.2 +14 -1
xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource.java
Index: IncrementalSAXSource.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IncrementalSAXSource.java 2001/07/18 13:11:04 1.1
+++ IncrementalSAXSource.java 2001/07/20 18:48:11 1.2
@@ -59,7 +59,6 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import java.io.IOException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.XMLReader;
@@ -107,4 +106,18 @@
* */
public Object deliverMoreNodes (boolean parsemore);
+ // ------------------------------------------------------------------
+ // Parse Thread Convenience API
+ // ------------------------------------------------------------------
+
+ /** Launch an XMLReader's parsing operation, feeding events to this
+ * IncrementalSAXSource. In some implementations, this may launch a
+ * thread which runs the previously supplied XMLReader's parse() operation.
+ * In others, it may do other forms of initialization.
+ *
+ * @throws SAXException is parse thread is already in progress
+ * or parsing can not be started.
+ * */
+ public void startParse(InputSource source) throws SAXException;
+
} // class IncrementalSAXSource
1.2 +8 -6
xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Filter.java
Index: IncrementalSAXSource_Filter.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Filter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IncrementalSAXSource_Filter.java 2001/07/18 13:11:04 1.1
+++ IncrementalSAXSource_Filter.java 2001/07/20 18:48:11 1.2
@@ -171,6 +171,7 @@
* */
public void setXMLReader(XMLReader eventsource)
{
+ fXMLReader=eventsource;
eventsource.setContentHandler(this);
eventsource.setErrorHandler(this); // to report fatal errors in
filtering mode
@@ -603,14 +604,14 @@
* @throws SAXException is parse thread is already in progress
* or parsing can not be started.
* */
- void startParse(XMLReader reader,InputSource source) throws SAXException
+ public void startParse(InputSource source) throws SAXException
{
- if(fXMLReader!=null)
- throw new SAXException("startParse may not be called while parsing.");
+ if(fNoMoreEvents)
+ throw new SAXException("IncrmentalSAXSource_Filter not currently
restartable.");
+ if(fXMLReader==null)
+ throw new SAXException("XMLReader not before startParse request");
- fXMLReader=reader;
fXMLReaderInputSource=source;
- setXMLReader(reader);
// Xalan thread pooling...
org.apache.xalan.transformer.TransformerImpl.runTransformThread(this);
@@ -761,7 +762,8 @@
// init not issued; we _should_ automagically Do The Right Thing
// Bind parser, kick off parsing in a thread
- filter.startParse(theSAXParser,source);
+ filter.setXMLReader(theSAXParser);
+ filter.startParse(source);
for(result = filter.deliverMoreNodes(more);
(result instanceof Boolean && ((Boolean)result)==Boolean.TRUE);
1.2 +1 -1
xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
Index: IncrementalSAXSource_Xerces.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IncrementalSAXSource_Xerces.java 2001/07/18 13:11:04 1.1
+++ IncrementalSAXSource_Xerces.java 2001/07/20 18:48:11 1.2
@@ -148,7 +148,7 @@
* @throws SAXException is parse thread is already in progress
* or parsing can not be started.
* */
- void startParse(InputSource source) throws SAXException
+ public void startParse(InputSource source) throws SAXException
{
if (fIncrementalParser==null)
throw new SAXException("startParse needs a non-null SAXParser.");
1.15 +15 -14
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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- DOM2DTM.java 2001/07/17 18:37:04 1.14
+++ DOM2DTM.java 2001/07/20 18:48:11 1.15
@@ -202,7 +202,7 @@
{
int nodeIndex = m_nodes.size();
m_size++;
- ensureSize(nodeIndex);
+ // ensureSize(nodeIndex);
int type;
if(NULL==forceNodeType)
@@ -227,8 +227,6 @@
// so if it's read-only). The best available answer might be to
// synthesize additional DTM Namespace Nodes that don't correspond
// to DOM Attr Nodes.
- //
- // %REVIEW% With forceNodeType... Is this trip really necessary?
if (Node.ATTRIBUTE_NODE == type)
{
String name = node.getNodeName();
@@ -244,8 +242,8 @@
// Do casts here so that if we change the sizes, the changes are
localized.
// %REVIEW% Remember to change this cast if we change
// m_level's type, or we may truncate values without warning!
- //m_level[nodeIndex] = (byte)level;
- m_level.addElement((byte)level); // setElementAt(level,nodeIndex)?
+ if(!DTMDefaultBase.DISABLE_PRECALC_LEVEL)
+ m_level.addElement((byte)level); // setElementAt(level,nodeIndex)?
m_firstch.setElementAt(NOTPROCESSED,nodeIndex);
m_nextsib.setElementAt(NOTPROCESSED,nodeIndex);
@@ -522,9 +520,12 @@
// Inserting next. NOTE that we force the node type; for
// coalesced Text, this records CDATASections adjacent to
// ordinary Text as Text.
- int level=m_level.elementAt(m_last_parent)+1;
- int nextindex=addNode(next,level,m_last_parent,m_last_kid,
- nexttype);
+ int level=0;
+ if(!DTMDefaultBase.DISABLE_PRECALC_LEVEL)
+ level=m_level.elementAt(m_last_parent)+1;
+ int nextindex=addNode(next,level,m_last_parent,m_last_kid,
+ nexttype);
+
m_last_kid=nextindex;
if(ELEMENT_NODE == nexttype)
@@ -1379,13 +1380,13 @@
return false;
}
- /** Bind a CoroutineParser to this DTM. NOT RELEVANT for DOM2DTM, since
+ /** Bind an IncrementalSAXSource to this DTM. NOT RELEVANT for DOM2DTM,
since
* we're wrapped around an existing DOM.
*
- * @param coroutineParser The parser that we want to recieve events from
+ * @param source The IncrementalSAXSource that we want to recieve events
from
* on demand.
*/
- public void setCoroutineParser(CoroutineParser coroutineParser)
+ public void setIncrementalSAXSource(IncrementalSAXSource source)
{
}
@@ -1395,7 +1396,7 @@
*
* @return null if this model doesn't respond to SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrmentalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
* */
public org.xml.sax.ContentHandler getContentHandler()
@@ -1410,7 +1411,7 @@
*
* @return null if this model doesn't respond to lexical SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrementalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
*/
public org.xml.sax.ext.LexicalHandler getLexicalHandler()
@@ -1465,7 +1466,7 @@
}
/** @return true iff we're building this model incrementally (eg
- * we're partnered with a CoroutineParser) and thus require that the
+ * we're partnered with a IncrementalSAXSource) and thus require that the
* transformation and the parse run simultaneously. Guidance to the
* DTMManager.
* */
1.12 +82 -113
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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SAX2DTM.java 2001/07/16 18:01:37 1.11
+++ SAX2DTM.java 2001/07/20 18:48:11 1.12
@@ -97,25 +97,11 @@
* fallback, but that has all the known problems with multithreading
* on multiprocessors and we Don't Want to Go There.
*
- * @see setCoroutineParser
+ * @see setIncrementalSAXSource
*/
- private CoroutineParser m_coroutineParser = null;
+ private IncrementalSAXSource m_incrementalSAXSource = null;
/**
- * If we're building the model incrementally on demand, we need to
- * be able to tell the source who to return the data to.
- *
- * Note that if this has not been set, and you attempt to read ahead
- * of the current build point, we'll probably throw a MethodNotFound
- * exception. We could try to wait-and-retry instead, as a very poor
- * fallback, but that has all the known problems with multithreading
- * on multiprocessors and we Don't Want to Go There.
- *
- * @see setCoroutineParser
- */
- private int m_appCoroutineID = -1;
-
- /**
* All the character content, including attribute values, are stored in
* this buffer.
* %REVIEW% Should this have an option of being shared?
@@ -275,16 +261,6 @@
}
/**
- * Get the CoRoutine ID for the application.
- *
- * @return The CoRoutine ID for the application.
- */
- public int getAppCoroutineID()
- {
- return m_appCoroutineID;
- }
-
- /**
* Ask the CoRoutine parser to doTerminate and clear the reference.
*/
public void clearCoRoutine()
@@ -302,54 +278,49 @@
public void clearCoRoutine(boolean callDoTerminate)
{
- if (null != m_coroutineParser)
+ if (null != m_incrementalSAXSource)
{
if (callDoTerminate)
- m_coroutineParser.doTerminate(m_appCoroutineID);
+ m_incrementalSAXSource.deliverMoreNodes(false);
- m_coroutineParser = null;
+ m_incrementalSAXSource = null;
}
}
/**
- * Bind a CoroutineParser to this DTM. If we discover we need nodes
+ * Bind a IncrementalSAXSource to this DTM. If we discover we need nodes
* that have not yet been built, we will ask this object to send us more
* events, and it will manage interactions with its data sources.
*
- * Note that we do not actually build the CoroutineParser, since we don't
+ * Note that we do not actually build the IncrementalSAXSource, since we
don't
* know what source it's reading from, what thread that source will run in,
* or when it will run.
*
- * @param coroutineParser The parser that we want to recieve events from
+ * @param incrementalSAXSource The parser that we want to recieve events
from
* on demand.
* @param appCoRID The CoRoutine ID for the application.
*/
- public void setCoroutineParser(CoroutineParser coroutineParser,
- int appCoRID)
+ public void setIncrementalSAXSource(IncrementalSAXSource
incrementalSAXSource)
{
// Establish coroutine link so we can request more data
//
- // Note: It's possible that some versions of CoroutineParser may
+ // Note: It's possible that some versions of IncrementalSAXSource may
// not actually use a CoroutineManager, and hence may not require
// that we obtain an Application Coroutine ID. (This relies on the
// coroutine transaction details having been encapsulated in the
- // CoroutineParser.do...() methods.)
- m_coroutineParser = coroutineParser;
-
- CoroutineManager cm = coroutineParser.getCoroutineManager();
+ // IncrementalSAXSource.do...() methods.)
+ m_incrementalSAXSource = incrementalSAXSource;
- m_appCoroutineID = appCoRID;
-
// Establish SAX-stream link so we can receive the requested data
- coroutineParser.setContentHandler(this);
- coroutineParser.setLexHandler(this);
+ incrementalSAXSource.setContentHandler(this);
+ incrementalSAXSource.setLexicalHandler(this);
- // Are the following really needed? coroutineParser doesn't yet
+ // Are the following really needed? incrementalSAXSource doesn't yet
// support them, and they're mostly no-ops here...
- //coroutineParser.setErrorHandler(this);
- //coroutineParser.setDTDHandler(this);
- //coroutineParser.setDeclHandler(this);
+ //incrementalSAXSource.setErrorHandler(this);
+ //incrementalSAXSource.setDTDHandler(this);
+ //incrementalSAXSource.setDeclHandler(this);
}
/**
@@ -361,14 +332,14 @@
*
* @return null if this model doesn't respond to SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrementalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
*/
public ContentHandler getContentHandler()
{
- if (m_coroutineParser instanceof CoroutineSAXParser)
- return (ContentHandler) m_coroutineParser;
+ if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter)
+ return (ContentHandler) m_incrementalSAXSource;
else
return this;
}
@@ -380,14 +351,14 @@
*
* @return null if this model doesn't respond to lexical SAX events,
* "this" if the DTM object has a built-in SAX ContentHandler,
- * the CoroutineParser if we're bound to one and should receive
+ * the IncrementalSAXSource if we're bound to one and should receive
* the SAX stream via it for incremental build purposes...
*/
public LexicalHandler getLexicalHandler()
{
- if (m_coroutineParser instanceof CoroutineSAXParser)
- return (LexicalHandler) m_coroutineParser;
+ if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter)
+ return (LexicalHandler) m_incrementalSAXSource;
else
return this;
}
@@ -434,13 +405,13 @@
/**
* @return true iff we're building this model incrementally (eg
- * we're partnered with a CoroutineParser) and thus require that the
+ * we're partnered with a IncrementalSAXSource) and thus require that the
* transformation and the parse run simultaneously. Guidance to the
* DTMManager.
*/
public boolean needsTwoThreads()
{
- return null != m_coroutineParser;
+ return null != m_incrementalSAXSource;
}
/**
@@ -553,27 +524,30 @@
{
int expandedTypeID = getExpandedTypeID(nodeHandle);
- int namespaceID = (expandedTypeID & ExpandedNameTable.MASK_NAMESPACE)
- >> ExpandedNameTable.BITS_PER_LOCALNAME;
+ // If just testing nonzero, no need to shift...
+ //int namespaceID = (expandedTypeID & ExpandedNameTable.MASK_NAMESPACE)
+ // >> ExpandedNameTable.BITS_PER_LOCALNAME;
+ int namespaceID = (expandedTypeID & ExpandedNameTable.MASK_NAMESPACE);
if (0 == namespaceID)
{
- String name = m_expandedNameTable.getLocalName(expandedTypeID);
+ // Don't retrieve name until/unless needed
+ // String name = m_expandedNameTable.getLocalName(expandedTypeID);
int type = getNodeType(nodeHandle);
if (type == DTM.NAMESPACE_NODE)
{
- if (name == null)
+ if (null == m_expandedNameTable.getLocalName(expandedTypeID))
return "xmlns";
else
- return "xmlns:" + name;
+ return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID);
}
else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID))
{
return m_fixednames[type];
}
else
- return name;
+ return m_expandedNameTable.getLocalName(expandedTypeID);
}
else
{
@@ -676,7 +650,7 @@
while (identity >= m_size)
{
- if (null == m_coroutineParser)
+ if (null == m_incrementalSAXSource)
return DTM.NULL;
nextNode();
@@ -737,7 +711,7 @@
protected boolean nextNode()
{
- if (null == m_coroutineParser)
+ if (null == m_incrementalSAXSource)
return false;
if (m_endDocumentOccured)
@@ -747,10 +721,10 @@
return false;
}
- Object gotMore = m_coroutineParser.doMore(true, m_appCoroutineID);
+ Object gotMore = m_incrementalSAXSource.deliverMoreNodes(true);
// gotMore may be a Boolean (TRUE if still parsing, FALSE if
- // EOF) or an exception if CoroutineParser malfunctioned
+ // EOF) or an exception if IncrementalSAXSource malfunctioned
// (code error rather than user error).
//
// %REVIEW% Currently the ErrorHandlers sketched herein are
@@ -798,21 +772,21 @@
return (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type);
}
- /**
- * Ensure that the size of the information arrays can hold another entry
- * at the given index.
- *
- * @param on exit from this function, the information arrays sizes must be
- * at least index+1.
- *
- * NEEDSDOC @param index
- */
- protected void ensureSize(int index)
- {
- // dataOrQName is an SuballocatedIntVector and hence self-sizing.
- // But DTMDefaultBase may need fixup.
- super.ensureSize(index);
- }
+// /**
+// * Ensure that the size of the information arrays can hold another
entry
+// * at the given index.
+// *
+// * @param on exit from this function, the information arrays sizes
must be
+// * at least index+1.
+// *
+// * NEEDSDOC @param index
+// */
+// protected void ensureSize(int index)
+// {
+// // dataOrQName is an SuballocatedIntVector and hence self-sizing.
+// // But DTMDefaultBase may need fixup.
+// super.ensureSize(index);
+// }
/**
* Construct the node map from the node.
@@ -833,46 +807,41 @@
int dataOrPrefix, boolean canHaveFirstChild)
{
+ // Common to all nodes:
int nodeIndex = m_size++;
-
- ensureSize(nodeIndex);
-
- if (m_useSourceLocationProperty && m_locator != null) {
- m_sourceSystemId.addElement(m_locator.getSystemId());
- m_sourceLine.addElement(m_locator.getLineNumber());
- m_sourceColumn.addElement(m_locator.getColumnNumber());
-
- if (m_sourceSystemId.size() != m_size) {
- System.out.println("size array " + m_size
- + " is different from size of array "
- + m_sourceSystemId.size());
- System.exit(1);
- }
- }
-
- // Do the hard casts here, so we localize changes that may have to be
made.
- m_level.addElement((byte)level); // %REVIEW%
setElementAt(level,nodeIndex)?
- m_firstch.setElementAt(canHaveFirstChild ? NOTPROCESSED :
DTM.NULL,nodeIndex);
- m_nextsib.setElementAt(NOTPROCESSED,nodeIndex);
- m_prevsib.setElementAt(previousSibling,nodeIndex);
- m_parent.setElementAt(parentIndex,nodeIndex);
- m_exptype.setElementAt(expandedTypeID,nodeIndex);
- m_dataOrQName.setElementAt(dataOrPrefix,nodeIndex);
-
- if (DTM.NULL != parentIndex && type != DTM.ATTRIBUTE_NODE
- && type != DTM.NAMESPACE_NODE)
+ // %REVIEW% This is being phased out
+ if(!DTMDefaultBase.DISABLE_PRECALC_LEVEL)
{
- if (NOTPROCESSED == m_firstch.elementAt(parentIndex))
- m_firstch.setElementAt(nodeIndex,parentIndex);
+ // Do the hard casts here, to localize changes that may have to be
made.
+ m_level.addElement((byte)level);
}
+ m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL);
+ m_nextsib.addElement(NOTPROCESSED);
+ m_prevsib.addElement(previousSibling);
+ m_parent.addElement(parentIndex);
+ m_exptype.addElement(expandedTypeID);
+ m_dataOrQName.addElement(dataOrPrefix);
- // Note that we don't want nextSibling to be processed until
- // charactersFlush() is called.
if (DTM.NULL != previousSibling)
m_nextsib.setElementAt(nodeIndex,previousSibling);
- if(type == DTM.NAMESPACE_NODE)
- declareNamespaceInContext(parentIndex,nodeIndex);
+ // Note that nextSibling is not processed until charactersFlush()
+ // is called, to handle successive characters() events.
+
+ // Special handling by type: Declare namespaces, attach first child
+ switch(type)
+ {
+ case DTM.NAMESPACE_NODE:
+ declareNamespaceInContext(parentIndex,nodeIndex);
+ break;
+ case DTM.ATTRIBUTE_NODE:
+ break;
+ default:
+ if (DTM.NULL != parentIndex &&
+ NOTPROCESSED == m_firstch.elementAt(parentIndex))
+ m_firstch.setElementAt(nodeIndex,parentIndex);
+ break;
+ }
return nodeIndex;
}
1.4 +46 -36
xml-xalan/java/src/org/apache/xml/utils/SuballocatedIntVector.java
Index: SuballocatedIntVector.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/utils/SuballocatedIntVector.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SuballocatedIntVector.java 2001/07/05 21:13:17 1.3
+++ SuballocatedIntVector.java 2001/07/20 18:48:11 1.4
@@ -71,7 +71,10 @@
*
* Current chunking is based on /%. Shift/mask _should_ be faster, if
* power-of-two chunksizes are acceptable. (Would be in a real language,
- * anyway...)
+ * anyway...) Some compilers _may_ be smart enough to convert the former
+ * to the latter if the block size is a constant power of two... so we have
+ * our choice of locking in a specific size, or converting to shift/mask,
+ * or both...
*
* Some methods are private because they haven't yet been tested properly.
*
@@ -163,21 +166,29 @@
m_map0[m_firstFree++]=value;
else
{
+ // Growing the outer array should be rare. We initialize to a
+ // total of m_blocksize squared elements, which at the default
+ // size is 4M integers... and we grow by at least that much each
+ // time. However, attempts to microoptimize for this (assume
+ // long enough and catch exceptions) yield no noticable
+ // improvement.
+
int index=m_firstFree/m_blocksize;
int offset=m_firstFree%m_blocksize;
- ++m_firstFree;
if(index>=m_map.length)
{
- int newsize=index+m_numblocks;
- int[][] newMap=new int[newsize][];
- System.arraycopy(m_map, 0, newMap, 0, m_map.length);
- m_map=newMap;
+ int newsize=index+m_numblocks;
+ int[][] newMap=new int[newsize][];
+ System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+ m_map=newMap;
}
int[] block=m_map[index];
if(null==block)
- block=m_map[index]=new int[m_blocksize];
+ block=m_map[index]=new int[m_blocksize];
block[offset]=value;
+
+ ++m_firstFree;
}
}
@@ -255,8 +266,8 @@
{
if(at==m_firstFree)
addElement(value);
- else if (at>m_firstFree)
- {
+ else if (at>m_firstFree)
+ {
int index=at/m_blocksize;
if(index>=m_map.length)
{
@@ -269,13 +280,13 @@
if(null==block)
block=m_map[index]=new int[m_blocksize];
int offset=at%m_blocksize;
- block[offset]=value;
- m_firstFree=offset+1;
- }
+ block[offset]=value;
+ m_firstFree=offset+1;
+ }
else
{
int index=at/m_blocksize;
- int maxindex=m_firstFree+1/m_blocksize;
+ int maxindex=m_firstFree/m_blocksize; // %REVIEW% (m_firstFree+1?)
++m_firstFree;
int offset=at%m_blocksize;
int push;
@@ -341,7 +352,7 @@
*/
private void removeElementAt(int at)
{
- // No point in removing elements that "don't exist"...
+ // No point in removing elements that "don't exist"...
if(at<m_firstFree)
{
int index=at/m_blocksize;
@@ -384,30 +395,30 @@
public void setElementAt(int value, int at)
{
if(at<m_blocksize)
- {
m_map0[at]=value;
- return;
- }
-
- int index=at/m_blocksize;
- int offset=at%m_blocksize;
-
- if(index>=m_map.length)
+ else
{
- int newsize=index+m_numblocks;
- int[][] newMap=new int[newsize][];
- System.arraycopy(m_map, 0, newMap, 0, m_map.length);
- m_map=newMap;
- }
+ int index=at/m_blocksize;
+ int offset=at%m_blocksize;
+
+ if(index>=m_map.length)
+ {
+ int newsize=index+m_numblocks;
+ int[][] newMap=new int[newsize][];
+ System.arraycopy(m_map, 0, newMap, 0, m_map.length);
+ m_map=newMap;
+ }
- int[] block=m_map[index];
- if(null==block)
- block=m_map[index]=new int[m_blocksize];
- block[offset]=value;
+ int[] block=m_map[index];
+ if(null==block)
+ block=m_map[index]=new int[m_blocksize];
+ block[offset]=value;
+ }
if(at>=m_firstFree)
m_firstFree=at+1;
}
+
/**
* Get the nth element. This is often at the innermost loop of an
@@ -432,8 +443,7 @@
*/
public int elementAt(int i)
{
- // %OPT% Does this really buy us anything? Test versus division for
small,
- // test _plus_ division for big docs.
+ // %OPT% Seems to buy us some very slight performance gains.
if(i<m_blocksize)
return m_map0[i];
@@ -465,9 +475,9 @@
*/
public int indexOf(int elem, int index)
{
- if(index>=m_firstFree)
- return -1;
-
+ if(index>=m_firstFree)
+ return -1;
+
int bindex=index/m_blocksize;
int boffset=index%m_blocksize;
int maxindex=m_firstFree/m_blocksize;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]