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]

Reply via email to