sboag       00/10/17 12:20:57

  Modified:    java/src/org/apache/xalan/transformer TransformerImpl.java
  Log:
  Used StringBuffer pooling, ResultTreeHandler pooling.
  Changed pushes of current context node and template to single node list with 
pushPair and popPair methods.
  Other minor changes.
  
  Revision  Changes    Path
  1.36      +145 -89   
xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- TransformerImpl.java      2000/10/16 22:56:04     1.35
  +++ TransformerImpl.java      2000/10/17 19:20:55     1.36
  @@ -90,6 +90,7 @@
   import org.apache.xalan.utils.BoolStack;
   import org.apache.xalan.utils.QName;
   import org.apache.xalan.utils.PrefixResolver;
  +import org.apache.xalan.utils.ObjectPool;
   
   import org.apache.xpath.XPathContext;
   import org.apache.xpath.NodeSet;
  @@ -200,10 +201,8 @@
       m_countersTable = null;
       m_stackGuard = new StackGuard();
       getXPathContext().reset();
  -    m_currentTemplateElements = new Stack();
  -    m_currentNodes = new Stack();
  -    m_currentMatchTemplates = new Stack();
  -    m_currentMatchNodes = new Stack();
  +    m_currentTemplateElements.removeAllElements();
  +    m_currentMatchTemplates.removeAllElements();
       m_resultTreeHandler = null;
       m_keyManager = new KeyManager();
       m_attrSetStack = null;
  @@ -248,8 +247,30 @@
     {
       return m_parserEventsOnMain;
     }
  -    
  +  
  +  private Thread m_transformThread;
  +  
  +  /**
  + * <meta name="usage" content="internal"/>
  +   * Get the thread that the transform process is on.
  +   * This may return null.
  +   */
  +  public Thread getTransformThread()
  +  {
  +    return m_transformThread;
  +  }
  +
     /**
  + * <meta name="usage" content="internal"/>
  +   * Get the thread that the transform process is on.
  +   * This may return null.
  +   */
  +  public void setTransformThread(Thread t)
  +  {
  +    m_transformThread = t;
  +  }
  +
  +  /**
      * Process the source tree to SAX parse events.
      * @param xmlSource  The input for the source tree.
      */
  @@ -335,7 +356,9 @@
             throw new org.apache.trax.TransformException(
               
((org.apache.xalan.utils.WrappedRuntimeException)e).getException());
           else
  +        {
             throw new org.apache.trax.TransformException(e);
  +        }
         }
         else if(null != m_resultTreeHandler)
         {
  @@ -865,14 +888,17 @@
       vars.pushContextMarker();
       
       int n = m_newVars.size();
  -    for(int i = 0; i < n; i++)
  +    if(n > 0)
       {
  -      vars.push((Arg)m_newVars.elementAt(i));
  +      for(int i = 0; i < n; i++)
  +      {
  +        vars.push((Arg)m_newVars.elementAt(i));
  +      }
  +      
  +      // Dragons check: make sure this is nulling the refs.
  +      m_newVars.removeAllElements();
       }
       
  -    // Dragons check: make sure this is nulling the refs.
  -    m_newVars.removeAllElements();
  -    
     } // end pushParams method
     
     /**
  @@ -1005,6 +1031,29 @@
       return resultFragment;
     }  
     
  +  private ObjectPool m_textResultHandlerObjectPool 
  +    = new ObjectPool(org.apache.xalan.transformer.ResultTreeHandler.class);
  +
  +  private ObjectPool m_stringWriterObjectPool 
  +    = new ObjectPool(java.io.StringWriter.class);
  +  
  +  /** 
  +   * <meta name="usage" content="internal"/>
  +   * 
  +   */
  +  public ObjectPool getStringWriterPool()
  +  {
  +    return m_stringWriterObjectPool;
  +  }
  +  
  +  private static OutputFormat m_textformat;
  +  static
  +  {
  +    m_textformat = new OutputFormat();
  +    m_textformat.setMethod("text");
  +    m_textformat.setPreserveSpace(true);
  +  }
  +
     /** 
      * <meta name="usage" content="advanced"/>
      * Take the contents of a template element, process it, and
  @@ -1021,45 +1070,65 @@
                                    Node sourceNode,
                                    QName mode)
       throws SAXException
  -  {    
  +  {        
       // Save the current result tree handler.
       ResultTreeHandler savedRTreeHandler = this.m_resultTreeHandler;
       
       // Create a Serializer object that will handle the SAX events 
       // and build the ResultTreeFrag nodes.
  -    ContentHandler shandler;
  -    StringWriter sw;
  +    StringWriter sw 
  +      = (StringWriter)m_stringWriterObjectPool.getInstance();
  +    m_resultTreeHandler 
  +      = (ResultTreeHandler)m_textResultHandlerObjectPool.getInstance();
  +    Serializer serializer = m_resultTreeHandler.getSerializer();
       try
       {
  -      // SerializerFactory sfactory 
  -      //  = SerializerFactory.getSerializerFactory("text");
  -      sw = new StringWriter();
  -      OutputFormat format = new OutputFormat();
  -      format.setMethod("text");
  -      format.setPreserveSpace(true);
  -      Serializer serializer = SerializerFactory.getSerializer(format);
  -      serializer.setWriter(sw);
  -      shandler = serializer.asContentHandler();
  +      if(null == serializer)
  +      {
  +        serializer = SerializerFactory.getSerializer(m_textformat);
  +        m_resultTreeHandler.setSerializer(serializer);
  +        serializer.setWriter(sw);
  +        ContentHandler shandler = serializer.asContentHandler();
  +        m_resultTreeHandler.init(this, shandler);
  +      }
  +      else
  +      {
  +        // serializer.setWriter(sw);
  +        // serializer.setOutputFormat(m_textformat);
  +        // ContentHandler shandler = serializer.asContentHandler();
  +        // m_resultTreeHandler.setContentHandler(shandler);
  +      }
       }
       catch(IOException ioe)
       {
         throw new SAXException(ioe);
       }
  -
  -    // And make a new handler that will write to the RTF.
  -    this.m_resultTreeHandler = new ResultTreeHandler(this, shandler);
       
  -    this.m_resultTreeHandler.startDocument();
  +    String result;
  +    try
  +    {
  +      this.m_resultTreeHandler.startDocument();
   
  -    // Do the transformation of the child elements.
  -    executeChildTemplates(elem, sourceNode, mode);
  -    
  -    this.m_resultTreeHandler.endDocument();
  -    
  -    // Restore the previous result tree handler.
  -    this.m_resultTreeHandler = savedRTreeHandler;
  -    
  -    return sw.toString();
  +      // Do the transformation of the child elements.
  +      executeChildTemplates(elem, sourceNode, mode);
  +      
  +      this.m_resultTreeHandler.endDocument();
  +      
  +      result = sw.toString();
  +    }
  +    finally
  +    {
  +      sw.getBuffer().setLength(0);
  +      try { sw.close(); } catch(Exception ioe) {}
  +      m_stringWriterObjectPool.freeInstance(sw);
  +      m_textResultHandlerObjectPool.freeInstance(m_resultTreeHandler);
  +      
  +      m_resultTreeHandler.reset();
  +      
  +      // Restore the previous result tree handler.
  +      m_resultTreeHandler = savedRTreeHandler;
  +    }
  +    return result;
     }
           
     /** 
  @@ -1261,21 +1330,20 @@
         // See http://www.w3.org/TR/xslt#built-in-rule.
         if(null == template)
         {
  -        StylesheetRoot root = m_stylesheetRoot;
           switch(nodeType)
           {
           case Node.DOCUMENT_FRAGMENT_NODE:
           case Node.ELEMENT_NODE:
  -          template = root.getDefaultRule();
  +          template = m_stylesheetRoot.getDefaultRule();
             break;
           case Node.CDATA_SECTION_NODE:
           case Node.TEXT_NODE:
           case Node.ATTRIBUTE_NODE:
  -          template = root.getDefaultTextRule();
  +          template = m_defaultTextRule;
             isDefaultTextRule = true;
             break;
           case Node.DOCUMENT_NODE:
  -          template = root.getDefaultRootRule();
  +          template = m_stylesheetRoot.getDefaultRootRule();
             break;
           default:
             // No default rules for processing instructions and the like.
  @@ -1288,15 +1356,14 @@
       // the value directly to the result tree.
       try
       {
  -      m_currentMatchTemplates.push(template);
  -      m_currentMatchNodes.push(child);
  +      m_currentMatchTemplates.pushPair(template, child);
         if(isDefaultTextRule)
         {
           switch(nodeType)
           {
           case Node.CDATA_SECTION_NODE:
           case Node.TEXT_NODE:
  -          getResultTreeHandler().cloneToResultTree(stylesheetTree, child, 
false, false, false);
  +          m_resultTreeHandler.m_cloner.cloneToResultTree(child, false);
             break;
           case Node.ATTRIBUTE_NODE:
             {
  @@ -1308,30 +1375,29 @@
         }
         else
         {
  -             // 9/11/00: If template has been compiled, hand off to it
  -             // since much (most? all?) of the processing has been inlined.
  -             // (It would be nice if there was a single entry point that
  -             // worked for both... but the interpretive system works by
  -             // having the Tranformer execute the children, while the
  -             // compiled obviously has to run its own code. It's
  -             // also unclear that "execute" is really the right name for
  -             // that entry point.)
  +        // 9/11/00: If template has been compiled, hand off to it
  +        // since much (most? all?) of the processing has been inlined.
  +        // (It would be nice if there was a single entry point that
  +        // worked for both... but the interpretive system works by
  +        // having the Tranformer execute the children, while the
  +        // compiled obviously has to run its own code. It's
  +        // also unclear that "execute" is really the right name for
  +        // that entry point.)
   
  -             // Fire a trace event for the template.
  +        // Fire a trace event for the template.
           if(TransformerImpl.S_DEBUG)
  -        getTraceManager().fireTraceEvent(child, mode, template);
  +          getTraceManager().fireTraceEvent(child, mode, template);
           
           // And execute the child templates.
  -             if(template instanceof 
org.apache.xalan.processor.CompiledTemplate)
  -                     template.execute(this,child,mode);
  -             else
  -                     executeChildTemplates(template, child, mode);
  +        if(template.isCompiledTemplate())
  +          template.execute(this,child,mode);
  +        else
  +          executeChildTemplates(template, child, mode);
         }
       }
       finally
       {
  -      m_currentMatchTemplates.pop();
  -      m_currentMatchNodes.pop();
  +      m_currentMatchTemplates.popPair();
       }
       return true;
     }
  @@ -1363,6 +1429,8 @@
         this.setContentHandler(savedHandler);
       }
     }
  +  
  +  private ElemTemplate m_defaultTextRule;
   
     /** 
      * <meta name="usage" content="advanced"/>
  @@ -1387,7 +1455,7 @@
       XPathContext xctxt = getXPathContext();
   
       // Check for infinite loops if we have to.
  -    boolean check = (getRecursionLimit() > -1);
  +    boolean check = (m_stackGuard.m_recursionLimit > -1);
       if (check)
         getStackGuard().push(elem, sourceNode);
       
  @@ -1399,25 +1467,20 @@
       Locator savedLocator = xctxt.getSAXLocator();
       try
       {
  +      pushElemTemplateElement(null, sourceNode);
         // Loop through the children of the template, calling execute on 
         // each of them.
         for (ElemTemplateElement t = firstChild; t != null; 
              t = t.getNextSiblingElem()) 
         {
           xctxt.setSAXLocator(t);
  -        try
  -        {
  -          pushElemTemplateElement(t, sourceNode);
  -          t.execute(this, sourceNode, mode);
  -        }
  -        finally
  -        {
  -          popElemTemplateElement();
  -        }
  +        m_currentTemplateElements.setTailSub1(t);
  +        t.execute(this, sourceNode, mode);
         }
       }
       finally
       {
  +      popElemTemplateElement();
         xctxt.setSAXLocator(savedLocator);
         // Pop all the variables in this element frame.
         varstack.popElemFrame();
  @@ -1455,14 +1518,12 @@
           String langString = (null != sort.getLang())
                               ? sort.getLang().evaluate(xctxt, 
                                                         sourceNodeContext, 
  -                                                      xslInstruction, 
  -                                                      new StringBuffer())
  +                                                      xslInstruction)
                                 : null;
           String dataTypeString 
             = sort.getDataType().evaluate(xctxt, 
                                           sourceNodeContext, 
  -                                        xslInstruction, 
  -                                        new StringBuffer());
  +                                        xslInstruction);
           if (dataTypeString.indexOf(":") >= 0 )
             System.out.println("TODO: Need to write the hooks for QNAME sort 
data type");        
           else if 
(!(dataTypeString.equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_TEXT)) && 
  @@ -1475,8 +1536,7 @@
               true : false;
           String orderString 
             = sort.getOrder().evaluate(xctxt, sourceNodeContext, 
  -                                     xslInstruction, 
  -                                     new StringBuffer());
  +                                     xslInstruction);
           if 
(!(orderString.equalsIgnoreCase(Constants.ATTRVAL_ORDER_ASCENDING)) && 
                              
!(orderString.equalsIgnoreCase(Constants.ATTRVAL_ORDER_DESCENDING)))
                              
xslInstruction.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new 
Object[] {Constants.ATTRNAME_ORDER, orderString});   
  @@ -1492,8 +1552,7 @@
             String caseOrderString 
               = caseOrder.evaluate(xctxt, 
                                    sourceNodeContext, 
  -                                 xslInstruction, 
  -                                 new StringBuffer());
  +                                 xslInstruction);
             if 
(!(caseOrderString.equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_UPPER)) && 
                              
!(caseOrderString.equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_LOWER)))
                              
xslInstruction.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE, new 
Object[] {Constants.ATTRNAME_CASEORDER, caseOrderString});   
  @@ -1520,16 +1579,14 @@
     // SECTION: TransformState implementation
     //==========================================================
     
  -  private Stack m_currentTemplateElements = new Stack();
  -  private Stack m_currentNodes = new Stack();
  +  private NodeVector m_currentTemplateElements = new NodeVector(64);
     
     /**
      * Push the current template element.
      */
     public void pushElemTemplateElement(ElemTemplateElement elem, Node 
currentNode)
     {
  -    m_currentTemplateElements.push(elem);
  -    m_currentNodes.push(currentNode);
  +    m_currentTemplateElements.pushPair(elem, currentNode);
     }
     
     /**
  @@ -1537,8 +1594,7 @@
      */
     public void popElemTemplateElement()
     {
  -    m_currentTemplateElements.pop();
  -    m_currentNodes.pop();
  +    m_currentTemplateElements.popPair();
     }
     
     /**
  @@ -1547,7 +1603,7 @@
      */
     public ElemTemplateElement getCurrentElement()
     {
  -    return (ElemTemplateElement)m_currentTemplateElements.peek();
  +    return (ElemTemplateElement)m_currentTemplateElements.peepTailSub1();
     }
   
     /**
  @@ -1556,7 +1612,7 @@
      */
     public Node getCurrentNode()
     {
  -    return (Node)m_currentNodes.peek();
  +    return m_currentTemplateElements.peepTail();
     }
     
     /**
  @@ -1576,8 +1632,7 @@
       return (ElemTemplate)elem;
     }
   
  -  private Stack m_currentMatchTemplates = new Stack();
  -  private Stack m_currentMatchNodes = new Stack();
  +  private NodeVector m_currentMatchTemplates = new NodeVector();
   
     /**
      * This method retrieves the xsl:template 
  @@ -1588,7 +1643,7 @@
      */
     public ElemTemplate getMatchedTemplate()
     {
  -    return (ElemTemplate)m_currentMatchTemplates.peek();
  +    return (ElemTemplate)m_currentMatchTemplates.peepTailSub1();
     }
   
     /**
  @@ -1597,7 +1652,7 @@
      */
     public Node getMatchedNode()
     {
  -    return (Node)m_currentMatchNodes.peek();
  +    return m_currentMatchTemplates.peepTail();
     }
     
     /**
  @@ -1644,6 +1699,7 @@
     public void setStylesheet(StylesheetRoot stylesheetRoot)
     {
       m_stylesheetRoot = stylesheetRoot;
  +    m_defaultTextRule = stylesheetRoot.getDefaultTextRule();
     }
   
     /**
  @@ -1886,7 +1942,7 @@
      * This is a compile-time flag to turn off calling 
      * of trace listeners. Set this to false for optimization purposes.
      */
  -  public static final boolean S_DEBUG = true;
  +  public static boolean S_DEBUG = false;
     
     /**
      * The trace manager.
  
  
  

Reply via email to