neilg 2002/08/13 15:32:44 Modified: java/src/org/apache/xerces/impl/xs XMLSchemaValidator.java java/src/org/apache/xerces/impl/xs/identity Field.java Selector.java XPathMatcher.java Log: more identity constraint performance fixes. Eliminated unnecessary endDocumentFragment calls for XPathMatchers. Selectors now do not attempt to examine character data; only fields need do this. Refactored some code and eliminated some unnecessary global variables from XPathMatcher. Revision Changes Path 1.79 +1 -5 xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java Index: XMLSchemaValidator.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v retrieving revision 1.78 retrieving revision 1.79 diff -u -r1.78 -r1.79 --- XMLSchemaValidator.java 12 Aug 2002 18:12:24 -0000 1.78 +++ XMLSchemaValidator.java 13 Aug 2002 22:32:44 -0000 1.79 @@ -2090,11 +2090,8 @@ XPathMatcher matcher = fMatcherStack.getMatcherAt(i); IdentityConstraint id; if ((id = matcher.getIDConstraint()) != null && id.getCategory() != IdentityConstraint.IC_KEYREF) { - matcher.endDocumentFragment(); fValueStoreCache.transplant(id); } - else if (id == null) - matcher.endDocumentFragment(); } // now handle keyref's/... for (int i = oldCount - 1; i >= newCount; i--) { @@ -2104,7 +2101,6 @@ ValueStoreBase values = fValueStoreCache.getValueStoreFor(id); if (values != null) // nothing to do if nothing matched! values.endDocumentFragment(); - matcher.endDocumentFragment(); } } fValueStoreCache.endElement(); 1.4 +2 -2 xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Field.java Index: Field.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Field.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Field.java 29 Jan 2002 01:15:15 -0000 1.3 +++ Field.java 13 Aug 2002 22:32:44 -0000 1.4 @@ -197,7 +197,7 @@ /** Constructs a field matcher. */ public Matcher(Field.XPath xpath, ValueStore store) { - super(xpath, true, null); + super(xpath, null); fStore = store; } // <init>(Field.XPath,ValueStore) 1.6 +14 -6 xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Selector.java Index: Selector.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/identity/Selector.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Selector.java 12 Aug 2002 18:12:24 -0000 1.5 +++ Selector.java 13 Aug 2002 22:32:44 -0000 1.6 @@ -64,9 +64,9 @@ import org.apache.xerces.xni.XNIException; import org.apache.xerces.xni.XMLAttributes; import org.apache.xerces.xni.psvi.ElementPSVI; -import org.apache.xerces.util.SymbolTable; import org.apache.xerces.impl.xs.XSElementDecl; import org.apache.xerces.impl.xs.XSAttributeGroupDecl; +import org.apache.xerces.util.SymbolTable; import org.xml.sax.SAXException; @@ -198,7 +198,7 @@ /** Constructs a selector matcher. */ public Matcher(Selector.XPath xpath, FieldActivator activator) { - super(xpath, false, Selector.this.fIdentityConstraint); + super(xpath, Selector.this.fIdentityConstraint); fFieldActivator = activator; } // <init>(Selector.XPath,FieldActivator) @@ -209,10 +209,9 @@ public void startDocumentFragment(SymbolTable symbolTable) throws XNIException { super.startDocumentFragment(symbolTable); - //super.startDocumentFragment(context, symbolTable); fElementDepth = 0; fMatchedDepth = -1; - } // startDocumentFragment(SymbolTable) + } // startDocumentFragment() /** * The start of an element. If the document specifies the start element @@ -251,6 +250,15 @@ fFieldActivator.endValueScopeFor(fIdentityConstraint); } } + + // + // Protected methods + // + + // overridden to do nothing; selectors don't care + // about element content + protected void handleContent(XSElementDecl eDecl, ElementPSVI ePSVI) { + } // handleContent(XSElementDecl, ElementPSVI) } // class Matcher 1.8 +73 -99 xml-xerces/java/src/org/apache/xerces/impl/xs/identity/XPathMatcher.java Index: XPathMatcher.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/identity/XPathMatcher.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- XPathMatcher.java 12 Aug 2002 18:12:24 -0000 1.7 +++ XPathMatcher.java 13 Aug 2002 22:32:44 -0000 1.8 @@ -116,6 +116,12 @@ DEBUG_MATCH || DEBUG_STACK; + // constants describing whether a match was made, + // and if so how. + protected static final int MATCHED = 1; + protected static final int MATCHED_ATTRIBUTE = 3; + protected static final int MATCHED_DESCENDANT = 5; + // // Data // @@ -123,17 +129,8 @@ /** XPath location path. */ private XPath.LocationPath[] fLocationPaths; - /** Application preference to buffer content or not. */ - private boolean fShouldBufferContent; - - /** True if should buffer character content <em>at this time</em>. */ - private boolean fBufferContent; - - /** Buffer to hold match text. */ - private StringBuffer fMatchedBuffer = new StringBuffer(); - /** True if XPath has been matched. */ - private boolean[] fMatched; + private int[] fMatched; /** The matching string. */ private String fMatchedString; @@ -150,20 +147,13 @@ */ private int [] fNoMatchDepth; - // Xerces 1.x framework - - /** Symbol table. */ - protected SymbolTable fSymbolTable; - - /** Namespace scope. */ - /*** REVISIT: do we need this? -NG - protected NamespaceContext fNamespacesScope; - */ - // the Identity constraint we're the matcher for. Only // used for selectors! protected IdentityConstraint fIDConstraint; + // the symbolTable for the XPath parser + protected SymbolTable fSymbolTable; + // // Constructors // @@ -175,7 +165,7 @@ * @param xpath The xpath. */ public XPathMatcher(XPath xpath) { - this(xpath, false, null); + this(xpath, null); } // <init>(XPath) /** @@ -188,15 +178,14 @@ * @param idConstraint: the identity constraint we're matching for; * null unless it's a Selector. */ - public XPathMatcher(XPath xpath, boolean shouldBufferContent, IdentityConstraint idConstraint) { + public XPathMatcher(XPath xpath, IdentityConstraint idConstraint) { fLocationPaths = xpath.getLocationPaths(); - fShouldBufferContent = shouldBufferContent; fIDConstraint = idConstraint; fStepIndexes = new IntStack[fLocationPaths.length]; for(int i=0; i<fStepIndexes.length; i++) fStepIndexes[i] = new IntStack(); fCurrentStep = new int[fLocationPaths.length]; fNoMatchDepth = new int[fLocationPaths.length]; - fMatched = new boolean[fLocationPaths.length]; + fMatched = new int[fLocationPaths.length]; if (DEBUG_METHODS) { System.out.println(toString()+"#<init>()"); } @@ -210,7 +199,7 @@ public boolean isMatched() { // xpath has been matched if any one of the members of the union have matched. for (int i=0; i < fLocationPaths.length; i++) - if (fMatched[i]) return true; + if ((fMatched[i] & MATCHED) == MATCHED) return true; return false; } // isMatched():boolean @@ -233,6 +222,31 @@ // Protected methods // + protected void handleContent(XSElementDecl eDecl, ElementPSVI ePSVI) { + fMatchedString = ePSVI.getSchemaNormalizedValue(); + // REVISIT: make sure type is simple! + XSSimpleType val=null; + + if (eDecl!=null) { + XSTypeDecl type = eDecl.fType; + if (type != null) { + if (type.getTypeCategory() == XSTypeDecl.COMPLEX_TYPE) { + XSComplexTypeDecl ctype = (XSComplexTypeDecl)type; + val = (XSSimpleType)ctype.getSimpleType(); + } + else { + val = (XSSimpleType)(type); + } + } + } + + if(eDecl != null) { + matched(fMatchedString, val, (eDecl.getIsNillable())); + } else { + matched(fMatchedString, val, false); + } + } // handleContent(XSElementDecl, ElementPSVI) + /** * This method is called when the XPath handler matches the * XPath expression. Subclasses can override this method to @@ -265,17 +279,17 @@ } // reset state - clear(); + fSymbolTable = symbolTable; + fMatchedString = null; for(int i = 0; i < fLocationPaths.length; i++) { fStepIndexes[i].clear(); fCurrentStep[i] = 0; fNoMatchDepth[i] = 0; + fMatched[i] = 0; } - // keep values - fSymbolTable = symbolTable; - } // startDocumentFragment(NamespaceContext) + } // startDocumentFragment(SymbolTable) /** * The start of an element. If the document specifies the start element @@ -304,7 +318,7 @@ fStepIndexes[i].push(startStep); // try next xpath, if not matching - if (fMatched[i] || fNoMatchDepth[i] > 0) { + if ((fMatched[i] & MATCHED) == MATCHED || fNoMatchDepth[i] > 0) { fNoMatchDepth[i]++; continue; } @@ -327,11 +341,7 @@ if (DEBUG_MATCH) { System.out.println(toString()+" XPath MATCHED!"); } - fMatched[i] = true; - int j=0; - for(; j<i && !fMatched[j]; j++); - if(j==i) - fBufferContent = fShouldBufferContent; + fMatched[i] = MATCHED; continue; } @@ -347,6 +357,7 @@ } fCurrentStep[i]++; } + boolean sawDescendant = fCurrentStep[i] > descendantStep; if (fCurrentStep[i] == steps.length) { if (DEBUG_MATCH) { System.out.println(toString()+" XPath DIDN'T MATCH!"); @@ -385,11 +396,11 @@ } } if (fCurrentStep[i] == steps.length) { - fMatched[i] = true; - int j=0; - for(; j<i && !fMatched[j]; j++); - if(j==i) - fBufferContent = fShouldBufferContent; + if(sawDescendant) { + fMatched[i] = MATCHED_DESCENDANT; + } else { + fMatched[i] = MATCHED; + } continue; } @@ -418,21 +429,20 @@ } } - for (int aindex = 0; aindex < attrCount; aindex++) { - attributes.getName(aindex, aname); + for (int aIndex = 0; aIndex < attrCount; aIndex++) { + attributes.getName(aIndex, aname); if (nodeTest.type != XPath.NodeTest.QNAME || nodeTest.name.equals(aname)) { fCurrentStep[i]++; if (fCurrentStep[i] == steps.length) { - fMatched[i] = true; + fMatched[i] = MATCHED_ATTRIBUTE; int j=0; - for(; j<i && !fMatched[j]; j++); + for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++); if(j==i) { - String avalue = attributes.getValue(aindex); + String avalue = attributes.getValue(aIndex); fMatchedString = avalue; - // now, we have to go on the hunt for - // datatype validator; not an easy or pleasant task... + // find Datatype validator... XSSimpleType aValidator = null; if (attrGrp != null) { XSAttributeUseImpl tempAttUse = attrGrp.getAttributeUse(aname.uri, aname.localpart); @@ -448,7 +458,7 @@ } } } - if (!fMatched[i]) { + if ((fMatched[i] & MATCHED) != MATCHED) { if(fCurrentStep[i] > descendantStep) { fCurrentStep[i] = descendantStep; continue; @@ -472,6 +482,7 @@ * * @param element The name of the element. * @param eDecl: the element declaration + * @param ePSVI contains validation info for this element * * @throws SAXException Thrown by handler to signal an error. */ @@ -483,6 +494,9 @@ ")"); } for(int i = 0; i<fLocationPaths.length; i++) { + // go back a step + fCurrentStep[i] = fStepIndexes[i].pop(); + // don't do anything, if not matching if (fNoMatchDepth[i] > 0) { fNoMatchDepth[i]--; @@ -491,39 +505,19 @@ // signal match, if appropriate else { int j=0; - for(; j<i && !fMatched[j]; j++); - if (j<i) continue; - if (fBufferContent) { - fBufferContent = false; - fMatchedString = ePSVI.getSchemaNormalizedValue(); - // REVISIT: make sure type is simple! - XSSimpleType val=null; - - if (eDecl!=null) { - XSTypeDecl type = eDecl.fType; - if (type != null) { - if (type.getTypeCategory() == XSTypeDecl.COMPLEX_TYPE) { - XSComplexTypeDecl ctype = (XSComplexTypeDecl)type; - val = (XSSimpleType)ctype.getSimpleType(); - } - else { - val = (XSSimpleType)(type); - } - } - } - - if(eDecl != null) { - matched(fMatchedString, val, (eDecl.getIsNillable())); - } else - matched(fMatchedString, val, false); - + for(; j<i && ((fMatched[j] & MATCHED) != MATCHED); j++); + if ((j<i) || (fMatched[j] == 0) || + ((fMatched[j] & MATCHED_ATTRIBUTE) == MATCHED_ATTRIBUTE)) { + continue; } - clear(); + // only certain kinds of matchers actually + // match element content. This permits + // them a way to override this to do nothing + // and hopefully save a few operations. + handleContent(eDecl, ePSVI); + fMatched[i] = 0; } - // go back a step - fCurrentStep[i] = fStepIndexes[i].pop(); - if (DEBUG_STACK) { System.out.println(toString()+": "+fStepIndexes[i]); } @@ -531,17 +525,6 @@ } // endElement(QName) - /** - * The end of the document fragment. - * - * @throws SAXException Thrown by handler to signal an error. - */ - public void endDocumentFragment() throws XNIException { - if (DEBUG_METHODS) { - System.out.println(toString()+"#endDocumentFragment()"); - } - } // endDocumentFragment() - // // Object methods // @@ -582,15 +565,6 @@ // // Private methods // - - /** Clears the match values. */ - private void clear() { - fBufferContent = false; - fMatchedBuffer.setLength(0); - fMatchedString = null; - for(int i = 0; i < fLocationPaths.length; i++) - fMatched[i] = false; - } // clear() /** Normalizes text. */ private String normalize(String s) {
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]