You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@apache.org on 2001/08/08 05:55:52 UTC

cvs commit: xml-xalan/java/src/org/apache/xpath/axes AxesWalker.java WalkerFactory.java WalkingIteratorSorted.java

sboag       01/08/07 20:55:52

  Modified:    java/src/org/apache/xpath/axes AxesWalker.java
                        WalkerFactory.java WalkingIteratorSorted.java
  Log:
  Eliminate do/while check for duplicates in AxesWalker#nextNode()
  by using WalkingIteratorSorted for cases where both the preceding[-sibling]
  and following[-sibling]  axes are being walked, and for "@*/foo" patterns
  ("@attr/foo" patterns still use WalkingIterator).
  
  Revision  Changes    Path
  1.22      +29 -46    xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java
  
  Index: AxesWalker.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- AxesWalker.java	2001/08/07 19:16:43	1.21
  +++ AxesWalker.java	2001/08/08 03:55:51	1.22
  @@ -243,7 +243,6 @@
       m_foundLast = false;
       m_root = root;
       m_currentNode = root;
  -    m_prevReturned = DTM.NULL;
   
       if (DTM.NULL == root)
       {
  @@ -376,60 +375,47 @@
       int nextNode = DTM.NULL;
       AxesWalker walker = wi().getLastUsedWalker();
   
  -    do
  +    while (true)
       {
  -      while (true)
  +      if (null == walker)
  +        break;
  +
  +      nextNode = walker.getNextNode();
  +
  +      if (DTM.NULL == nextNode)
         {
  -        if (null == walker)
  -          break;
   
  -        nextNode = walker.getNextNode();
  +        walker = walker.m_prevWalker;
  +      }
  +      else
  +      {
  +        if (walker.acceptNode(nextNode) != DTMIterator.FILTER_ACCEPT)
  +        {
  +          continue;
  +        }
   
  -        if (DTM.NULL == nextNode)
  +        if (null == walker.m_nextWalker)
           {
  +          wi().setLastUsedWalker(walker);
   
  -          walker = walker.m_prevWalker;
  +          // return walker.returnNextNode(nextNode);
  +          break;
           }
           else
           {
  -          if (walker.acceptNode(nextNode) != DTMIterator.FILTER_ACCEPT)
  -          {
  -            continue;
  -          }
  -
  -          if (null == walker.m_nextWalker)
  -          {
  -            wi().setLastUsedWalker(walker);
  -
  -            // return walker.returnNextNode(nextNode);
  -            break;
  -          }
  -          else
  -          {
  -            AxesWalker prev = walker;
  -
  -            walker = walker.m_nextWalker;
  -
  -            walker.setRoot(nextNode);
  -
  -            walker.m_prevWalker = prev;
  -
  -            continue;
  -          }
  -        }  // if(null != nextNode)
  -      }  // while(null != walker)
  -    }
  +          AxesWalker prev = walker;
  +
  +          walker = walker.m_nextWalker;
   
  -    // Not sure what is going on here, but we were loosing
  -    // the next node in the nodeset because it's coming from a 
  -    // different document. 
  -    while (
  -      (DTM.NULL != nextNode) && (DTM.NULL != m_prevReturned)
  -      && getDTM(nextNode).getDocument() == getDTM(m_prevReturned).getDocument()
  -      && getDTM(nextNode).isNodeAfter(nextNode, m_prevReturned));
  +          walker.setRoot(nextNode);
   
  -    m_prevReturned = nextNode;
  +          walker.m_prevWalker = prev;
   
  +          continue;
  +        }
  +      }  // if(null != nextNode)
  +    }  // while(null != walker)
  +
       return nextNode;
     }
   
  @@ -553,9 +539,6 @@
      */
     private transient int m_currentNode = DTM.NULL;
     
  -  /** The node last returned from nextNode(). */
  -  transient int m_prevReturned = DTM.NULL;
  -
     /** True if an itteration has not begun.  */
     transient boolean m_isFresh;
   
  
  
  
  1.20      +114 -12   xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java
  
  Index: WalkerFactory.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- WalkerFactory.java	2001/07/30 20:09:22	1.19
  +++ WalkerFactory.java	2001/08/08 03:55:51	1.20
  @@ -298,8 +298,17 @@
       }
       else
       { 
  -      if(canCrissCross(analysis) && !isSet(analysis, BIT_NAMESPACE))
  +      if(isNaturalDocOrder(compiler, firstStepPos, 0, analysis))
         {
  +        if (false || DEBUG_ITERATOR_CREATION)
  +        {
  +          diagnoseIterator("WalkingIterator", analysis, compiler);
  +        }
  +  
  +        iter = new WalkingIterator(compiler, opPos, analysis, true);
  +      }
  +      else
  +      {
   //        if (DEBUG_ITERATOR_CREATION)
   //          diagnoseIterator("MatchPatternIterator", analysis, compiler);
   //
  @@ -308,18 +317,7 @@
             diagnoseIterator("WalkingIteratorSorted", analysis, compiler);
   
           iter = new WalkingIteratorSorted(compiler, opPos, analysis, true);
  -
  -
         }
  -      else
  -      {
  -        if (false || DEBUG_ITERATOR_CREATION)
  -        {
  -          diagnoseIterator("WalkingIterator", analysis, compiler);
  -        }
  -  
  -        iter = new WalkingIterator(compiler, opPos, analysis, true);
  -      }
       }
       if(iter instanceof LocPathIterator)
         ((LocPathIterator)iter).setIsTopLevel(isTopLevel);
  @@ -1566,6 +1564,110 @@
         return true;
       else
         return false;
  +  }
  +  
  +  /**
  +   * Tell if the pattern can be 'walked' with the iteration steps in natural 
  +   * document order, without duplicates.
  +   *
  +   * @param compiler non-null reference to compiler object that has processed
  +   *                 the XPath operations into an opcode map.
  +   * @param stepOpCodePos The opcode position for the step.
  +   * @param stepIndex The top-level step index withing the iterator.
  +   * @param analysis The general analysis of the pattern.
  +   *
  +   * @return 32 bits as an integer that give information about the location
  +   * path as a whole.
  +   *
  +   * @throws javax.xml.transform.TransformerException
  +   */
  +  private static boolean isNaturalDocOrder(
  +          Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
  +            throws javax.xml.transform.TransformerException
  +  {
  +    if(canCrissCross(analysis))
  +      return false;
  +      
  +    // Namespaces can present some problems, so just punt if we're looking for 
  +    // these.
  +    if(isSet(analysis, BIT_NAMESPACE))
  +      return false;
  +      
  +    // The following, preceding, following-sibling, and preceding sibling can 
  +    // be found in doc order if we get to this point, but if they occur 
  +    // together, they produce 
  +    // duplicates, so it's better for us to eliminate this case so we don't 
  +    // have to check for duplicates during runtime if we're using a 
  +    // WalkingIterator.
  +    if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) && 
  +       isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING))
  +      return  false;
  +      
  +    // OK, now we have to check for select="@*/axis::*" patterns, which 
  +    // can also cause duplicates to happen.  But select="axis*/@::*" patterns 
  +    // are OK, as are select="@foo/axis::*" patterns.
  +    // Unfortunately, we can't do this just via the analysis bits.
  +
  +    int stepType;
  +    int ops[] = compiler.getOpMap();
  +    int stepCount = 0;
  +    boolean foundWildAttribute = false;
  +    
  +    while (OpCodes.ENDOP != (stepType = ops[stepOpCodePos]))
  +    {        
  +      stepCount++;
  +        
  +      switch (stepType)
  +      {
  +      case OpCodes.FROM_ATTRIBUTES :
  +      case OpCodes.MATCH_ATTRIBUTE :
  +        if(foundWildAttribute) // Maybe not needed, but be safe.
  +          return false;
  +        
  +        // This doesn't seem to work as a test for wild card.  Hmph.
  +        // int nodeTestType = compiler.getStepTestType(stepOpCodePos);  
  +        
  +        String localName = compiler.getStepLocalName(stepOpCodePos);
  +        // System.err.println("localName: "+localName);
  +        if(localName.equals("*"))
  +          foundWildAttribute = true;  
  +        break;
  +      case OpCodes.FROM_FOLLOWING :
  +      case OpCodes.FROM_FOLLOWING_SIBLINGS :
  +      case OpCodes.FROM_PRECEDING :
  +      case OpCodes.FROM_PRECEDING_SIBLINGS :
  +      case OpCodes.FROM_PARENT :
  +      case OpCodes.OP_VARIABLE :
  +      case OpCodes.OP_EXTFUNCTION :
  +      case OpCodes.OP_FUNCTION :
  +      case OpCodes.OP_GROUP :
  +      case OpCodes.FROM_NAMESPACE :
  +      case OpCodes.FROM_ANCESTORS :
  +      case OpCodes.FROM_ANCESTORS_OR_SELF :      
  +      case OpCodes.MATCH_ANY_ANCESTOR :
  +      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
  +      case OpCodes.FROM_ROOT :
  +      case OpCodes.FROM_CHILDREN :
  +      case OpCodes.FROM_DESCENDANTS_OR_SELF :
  +      case OpCodes.FROM_DESCENDANTS :
  +      case OpCodes.FROM_SELF :
  +        if(foundWildAttribute)
  +          return false;
  +        break;
  +      default :
  +        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
  +                                  // + stepType);
  +      }
  +
  +      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
  +
  +      if (nextStepOpCodePos < 0)
  +        break;
  +              
  +      stepOpCodePos = nextStepOpCodePos;
  +    }
  +
  +    return true;
     }
     
     public static boolean isOneStep(int analysis)
  
  
  
  1.6       +4 -4      xml-xalan/java/src/org/apache/xpath/axes/WalkingIteratorSorted.java
  
  Index: WalkingIteratorSorted.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/WalkingIteratorSorted.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- WalkingIteratorSorted.java	2001/08/07 19:16:43	1.5
  +++ WalkingIteratorSorted.java	2001/08/08 03:55:51	1.6
  @@ -127,7 +127,7 @@
         {
           int axis = walker.getAxis();
           boolean isSimpleDownAxis = ((axis == Axis.CHILD)
  -           || (axis == Axis.ATTRIBUTE) || (axis == Axis.SELF)
  +           || (axis == Axis.SELF)
              || (axis == Axis.ROOT));
           if(walker.isDocOrdered())
           {
  @@ -135,12 +135,12 @@
               walker = walker.getNextWalker();
             else
             {
  -            boolean nextIsNull = (null == walker.getNextWalker());
  -            if(nextIsNull)
  +            boolean isLastWalker = (null == walker.getNextWalker());
  +            if(isLastWalker)
               {
                 if(walker.isDocOrdered() && (axis == Axis.DESCENDANT || 
                    axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
  -                 || axis == Axis.DESCENDANTSORSELFFROMROOT))
  +                 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
                   return true;
               }
               return false;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org