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