dbertoni 01/07/20 22:35:16
Modified: c/src/XPath MutableNodeRefList.cpp MutableNodeRefList.hpp
SimpleNodeLocator.cpp XPath.cpp XPath.hpp
Log:
Fixed performance problems with reverse axes.
Revision Changes Path
1.19 +96 -70 xml-xalan/c/src/XPath/MutableNodeRefList.cpp
Index: MutableNodeRefList.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/MutableNodeRefList.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- MutableNodeRefList.cpp 2000/12/21 04:28:53 1.18
+++ MutableNodeRefList.cpp 2001/07/21 05:35:15 1.19
@@ -77,21 +77,24 @@
MutableNodeRefList::MutableNodeRefList() :
- NodeRefList()
+ NodeRefList(),
+ m_order(eUnknownOrder)
{
}
MutableNodeRefList::MutableNodeRefList(const MutableNodeRefList& theSource) :
- NodeRefList(theSource)
+ NodeRefList(theSource),
+ m_order(theSource.m_order)
{
}
MutableNodeRefList::MutableNodeRefList(const NodeRefListBase& theSource) :
- NodeRefList(theSource)
+ NodeRefList(theSource),
+ m_order(eUnknownOrder)
{
}
@@ -110,6 +113,8 @@
{
// Chain up...
NodeRefList::operator=(theRHS);
+
+ m_order = theRHS.m_order;
}
return *this;
@@ -124,6 +129,8 @@
{
// Chain up...
NodeRefList::operator=(theRHS);
+
+ m_order = eUnknownOrder;
}
return *this;
@@ -138,6 +145,8 @@
{
// Chain up...
NodeRefList::operator=(theRHS);
+
+ m_order = eUnknownOrder;
}
return *this;
@@ -165,8 +174,6 @@
{
if (n != 0)
{
- // ensureAllocation();
-
m_nodeList.push_back(n);
}
}
@@ -182,8 +189,6 @@
if (n != 0)
{
- // ensureAllocation();
-
m_nodeList.insert(m_nodeList.begin() + pos, n);
}
}
@@ -224,6 +229,8 @@
MutableNodeRefList::clear()
{
m_nodeList.clear();
+
+ m_order = eUnknownOrder;
}
@@ -240,61 +247,54 @@
-inline void
-MutableNodeRefList::ensureAllocation(NodeListVectorType::size_type /* theSize */)
+void
+MutableNodeRefList::addNodes(const XalanNodeList& nodelist)
{
- // This code is commmented out for now, since it appears to actual hurt
- // performance, rather than help.
-#if 0
- const unsigned int theNodeListSize = m_nodeList.size();
+ const unsigned int theLength = nodelist.getLength();
- if (theSize > theNodeListSize)
+ for (unsigned int i = 0; i < theLength; i++)
{
- const unsigned int theNewSize = theNodeListSize * 2;
+ XalanNode* const theNode = nodelist.item(i);
- if (theSize > theNewSize)
+ if (theNode != 0)
{
- m_nodeList.reserve(theSize * 2);
- }
- else
- {
- m_nodeList.reserve(theNewSize);
+
+ m_nodeList.push_back(theNode);
}
}
- else
- {
- m_nodeList.reserve(eDefaultVectorSize);
- }
-#endif
}
void
-MutableNodeRefList::addNodes(const XalanNodeList& nodelist)
+MutableNodeRefList::addNodes(const NodeRefListBase& nodelist)
{
const unsigned int theLength = nodelist.getLength();
- // ensureAllocation(m_nodeList.size() + theLength);
-
for (unsigned int i = 0; i < theLength; i++)
{
- addNode(nodelist.item(i));
+ XalanNode* const theNode = nodelist.item(i);
+
+ if (theNode != 0)
+ {
+
+ m_nodeList.push_back(theNode);
+ }
}
}
void
-MutableNodeRefList::addNodes(const NodeRefListBase& nodelist)
+MutableNodeRefList::addNodesInDocOrder(
+ const XalanNodeList& nodelist,
+ XPathExecutionContext& executionContext)
{
- const unsigned int theLength = nodelist.getLength();
+ const unsigned int theOtherLength = nodelist.getLength();
- // ensureAllocation(m_nodeList.size() + theLength);
-
- for (unsigned int i = 0; i < theLength; i++)
+ for(unsigned int i = 0; i < theOtherLength; i++)
{
- addNode(nodelist.item(i));
+ addNodeInDocOrder(nodelist.item(i), executionContext);
}
}
@@ -302,14 +302,12 @@
void
MutableNodeRefList::addNodesInDocOrder(
- const XalanNodeList& nodelist,
+ const NodeRefListBase& nodelist,
XPathExecutionContext& executionContext)
{
- const unsigned int theLength = nodelist.getLength();
-
- // ensureAllocation(m_nodeList.size() + theLength);
+ const unsigned int theOtherLength = nodelist.getLength();
- for(unsigned int i = 0; i < theLength; i++)
+ for(unsigned int i = 0; i < theOtherLength; i++)
{
addNodeInDocOrder(nodelist.item(i), executionContext);
}
@@ -319,16 +317,56 @@
void
MutableNodeRefList::addNodesInDocOrder(
- const NodeRefListBase& nodelist,
- XPathExecutionContext& executionContext)
+ const MutableNodeRefList& nodelist,
+ XPathExecutionContext& executionContext)
{
- const unsigned int theLength = nodelist.getLength();
+#if !defined(XALAN_NO_NAMESPACES)
+ using std::back_inserter;
+ using std::copy;
+ using std::for_each;
+#endif
- // ensureAllocation(m_nodeList.size() + theLength);
+ const eOrder theOtherOrder = nodelist.m_order;
- for(unsigned int i = 0; i < theLength; i++)
+ if (theOtherOrder == eUnknownOrder)
{
- addNodeInDocOrder(nodelist.item(i), executionContext);
+ for_each(
+ nodelist.m_nodeList.begin(),
+ nodelist.m_nodeList.end(),
+ addNodeInDocOrderFunctor(*this, executionContext));
+ }
+ else if (theOtherOrder == eDocumentOrder)
+ {
+ if (m_nodeList.empty() == true)
+ {
+ m_nodeList = nodelist.m_nodeList;
+ }
+ else
+ {
+ for_each(
+ nodelist.m_nodeList.begin(),
+ nodelist.m_nodeList.end(),
+ addNodeInDocOrderFunctor(*this, executionContext));
+ }
+ }
+ else
+ {
+ assert(theOtherOrder == eReverseDocumentOrder);
+
+ if (m_nodeList.empty() == true)
+ {
+ copy(
+ nodelist.m_nodeList.rbegin(),
+ nodelist.m_nodeList.rend(),
+ back_inserter(m_nodeList));
+ }
+ else
+ {
+ for_each(
+ nodelist.m_nodeList.rbegin(),
+ nodelist.m_nodeList.rend(),
+ addNodeInDocOrderFunctor(*this, executionContext));
+ }
}
}
@@ -555,8 +593,6 @@
{
const unsigned int size = m_nodeList.size();
- // ensureAllocation(size + 1);
-
if (size == 0)
{
addNode(node);
@@ -646,7 +682,6 @@
void
MutableNodeRefList::clearNulls()
{
-#if 1
#if !defined(XALAN_NO_NAMESPACES)
using std::remove;
#endif
@@ -658,29 +693,20 @@
NodeListVectorType::value_type(0)),
m_nodeList.end());
-#else
- NodeListVectorType::iterator i =
- m_nodeList.begin();
+ assert(checkForDuplicates() == false);
+}
- while(i != m_nodeList.end())
- {
- if (*i == 0)
- {
- NodeListVectorType::iterator j = i + 1;
- while(j != m_nodeList.end() && *j == 0)
- {
- ++j;
- }
- i = m_nodeList.erase(i, j);
- }
- else
- {
- ++i;
- }
- }
+void
+MutableNodeRefList::reverse()
+{
+#if !defined(XALAN_NO_NAMESPACES)
+ using std::reverse;
#endif
- assert(checkForDuplicates() == false);
+ reverse(
+ m_nodeList.begin(),
+ m_nodeList.end());
+
}
1.14 +91 -5 xml-xalan/c/src/XPath/MutableNodeRefList.hpp
Index: MutableNodeRefList.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/MutableNodeRefList.hpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- MutableNodeRefList.hpp 2000/12/21 04:28:53 1.13
+++ MutableNodeRefList.hpp 2001/07/21 05:35:15 1.14
@@ -193,7 +193,7 @@
* @param nodelist node list to add
* @param executionContext the current execution context
*/
- virtual void
+ void
addNodesInDocOrder(
const XalanNodeList& nodelist,
XPathExecutionContext& executionContext);
@@ -204,10 +204,21 @@
* @param nodelist node list to add
* @param executionContext the current execution context
*/
- virtual void
+ void
addNodesInDocOrder(
const NodeRefListBase& nodelist,
XPathExecutionContext& executionContext);
+
+ /**
+ * Copy NodeList members into this nodelist, adding in document order.
+ *
+ * @param nodelist node list to add
+ * @param executionContext the current execution context
+ */
+ void
+ addNodesInDocOrder(
+ const MutableNodeRefList& nodelist,
+ XPathExecutionContext& executionContext);
/**
* Add a node into list where it should occur in document order.
@@ -215,7 +226,7 @@
* @param node node object to add
* @param executionContext the current execution context
*/
- virtual void
+ void
addNodeInDocOrder(
XalanNode* node,
XPathExecutionContext& executionContext);
@@ -226,12 +237,87 @@
void
clearNulls();
+ /**
+ * Reverse the nodes in the list.
+ */
+ void
+ reverse();
+
+ /**
+ * Reserve space for the supplied number of nodes.
+ * This is taken as an optimization, and may be
+ * ignored. You might want to call this when you
+ * know the number of nodes you're about to add to
+ * this list.
+ *
+ * Remember to take into account the current size of
+ * the list when calling this. That means you will
+ * probably want to add the result of getLength() to
+ * the number of nodes you're planning to add.
+ *
+ * @param theCount the number of nodes to reserve space for
+ */
+ void
+ reserve(unsigned int theCount)
+ {
+ m_nodeList.reserve(theCount);
+ }
+
+ /**
+ * Set the known order of the nodes. This should
+ * only be done when the order is known. Otherwise,
+ * disaster will ensue.
+ */
+ void
+ setDocumentOrder()
+ {
+ m_order = eDocumentOrder;
+ }
+
+ /**
+ * Set the known order of the nodes. This should
+ * only be done when the order is known. Otherwise,
+ * disaster will ensue.
+ */
+ void
+ setReverseDocumentOrder()
+ {
+ m_order = eReverseDocumentOrder;
+ }
+
typedef NodeListVectorType::iterator NodeListIteratorType;
+ class addNodeInDocOrderFunctor
+ {
+ public:
+
+ addNodeInDocOrderFunctor(
+ MutableNodeRefList& theList,
+ XPathExecutionContext& theExecutionContext) :
+ m_list(theList),
+ m_executionContext(theExecutionContext)
+ {
+ }
+
+ void
+ operator()(XalanNode* theNode) const
+ {
+ m_list.addNodeInDocOrder(theNode, m_executionContext);
+ }
+
+ private:
+
+ MutableNodeRefList& m_list;
+
+ XPathExecutionContext& m_executionContext;
+ };
+
private:
- void
- ensureAllocation(NodeListVectorType::size_type theSize = 0);
+ // An enum to determine what the order of the nodes is...
+ enum eOrder { eUnknownOrder, eDocumentOrder, eReverseDocumentOrder };
+
+ eOrder m_order;
};
1.41 +28 -4 xml-xalan/c/src/XPath/SimpleNodeLocator.cpp
Index: SimpleNodeLocator.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/SimpleNodeLocator.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- SimpleNodeLocator.cpp 2001/07/08 18:40:08 1.40
+++ SimpleNodeLocator.cpp 2001/07/21 05:35:15 1.41
@@ -147,8 +147,7 @@
case XPathExpression::eOP_EXTFUNCTION:
case XPathExpression::eOP_FUNCTION:
case XPathExpression::eOP_GROUP:
- argLen = findNodeSet(xpath, executionContext, context, opPos,
- stepType, *subQueryResults);
+ argLen = findNodeSet(xpath, executionContext, context, opPos,
stepType, *subQueryResults);
break;
case XPathExpression::eFROM_ROOT:
@@ -640,7 +639,6 @@
const NodeRefListBase& nl = obj->nodeset();
- // $$$ ToDo: Should this be adding in doc order?
subQueryResults.addNodes(nl);
return currentExpression.getOpCodeLengthFromOpMap(opPos);
@@ -721,6 +719,8 @@
}
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -765,6 +765,8 @@
subQueryResults.addNode(context);
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -810,6 +812,8 @@
contextNode = DOMServices::getParentOfNode(*contextNode);
}
+ subQueryResults.setReverseDocumentOrder();
+
return argLen + 3;
}
@@ -857,6 +861,8 @@
contextNode = DOMServices::getParentOfNode(*contextNode);
}
+ subQueryResults.setReverseDocumentOrder();
+
return argLen + 3;
}
@@ -961,6 +967,8 @@
child = child->getNextSibling();
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -1030,6 +1038,8 @@
pos = nextNode;
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -1121,6 +1131,8 @@
pos = nextNode;
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -1165,6 +1177,8 @@
pos = pos->getNextSibling();
}
+ subQueryResults.setDocumentOrder();
+
return argLen + 3;
}
@@ -1239,7 +1253,7 @@
if(isParent == false)
{
- subQueryResults.insertNode(pos, 0);
+ subQueryResults.addNode(pos);
}
}
@@ -1276,10 +1290,18 @@
pos = nextNode;
}
+ // Now, reverse the order of the nodes, since
+ // preceeding is a reverse axis, and we searched
+ // the document from the root to this node.
+ subQueryResults.reverse();
+
+ subQueryResults.setReverseDocumentOrder();
+
return argLen + 3;
}
+
int
SimpleNodeLocator::findPreceedingSiblings(
const XPath& xpath,
@@ -1318,6 +1340,8 @@
pos = pos->getPreviousSibling();
}
+
+ subQueryResults.setReverseDocumentOrder();
return argLen + 3;
}
1.60 +0 -78 xml-xalan/c/src/XPath/XPath.cpp
Index: XPath.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.cpp,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -r1.59 -r1.60
--- XPath.cpp 2001/07/18 04:23:34 1.59
+++ XPath.cpp 2001/07/21 05:35:15 1.60
@@ -509,20 +509,6 @@
-MutableNodeRefList*
-XPath::step(
- XalanNode* context,
- int /* opPos */,
- XPathExecutionContext& executionContext) const
-{
- executionContext.warn(TranscodeFromLocalCodePage("XPath needs a derived object
to implement step!"),
- context);
-
- return 0;
-}
-
-
-
const XObjectPtr
XPath::Or(
XalanNode* context,
@@ -937,17 +923,6 @@
const XObjectPtr
-XPath::group(
- XalanNode* context,
- int opPos,
- XPathExecutionContext& executionContext) const
-{
- return executeMore(context, opPos + 2, executionContext);
-}
-
-
-
-const XObjectPtr
XPath::numberlit(
XalanNode* /* context */,
int opPos,
@@ -971,17 +946,6 @@
const XObjectPtr
-XPath::arg(
- XalanNode* context,
- int opPos,
- XPathExecutionContext& executionContext) const
-{
- return executeMore(context, opPos + 2, executionContext);
-}
-
-
-
-const XObjectPtr
XPath::locationPath(
XalanNode* context,
int opPos,
@@ -995,17 +959,6 @@
const XObjectPtr
-XPath::predicate(
- XalanNode* context,
- int opPos,
- XPathExecutionContext& executionContext) const
-{
- return executeMore(context, opPos + 2, executionContext);
-}
-
-
-
-const XObjectPtr
XPath::locationPathPattern(
XalanNode* context,
int opPos,
@@ -1058,23 +1011,6 @@
const XObjectPtr
-XPath::extfunction(
- XalanNode*
context,
- int
/* opPos */,
- const XalanDOMString&
theNamespace,
- const XalanDOMString&
functionName,
- const Function::XObjectArgVectorType& argVec,
- XPathExecutionContext&
executionContext) const
-{
- return executionContext.extFunction(theNamespace,
-
functionName,
-
context,
-
argVec);
-}
-
-
-
-const XObjectPtr
XPath::runFunction(
XalanNode* context,
int opPos,
@@ -1175,20 +1111,6 @@
return function(context, opPos, funcID, args, executionContext);
}
-}
-
-
-
-const XObjectPtr
-XPath::function(
- XalanNode*
context,
- int
opPos,
- int
funcID,
- const Function::XObjectArgVectorType& argVec,
- XPathExecutionContext&
executionContext) const
-
-{
- return s_functions[funcID].execute(executionContext, context, opPos, argVec);
}
1.28 +24 -20 xml-xalan/c/src/XPath/XPath.hpp
Index: XPath.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.hpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- XPath.hpp 2001/07/12 04:35:44 1.27
+++ XPath.hpp 2001/07/21 05:35:15 1.28
@@ -307,7 +307,10 @@
predicate(
XalanNode* context,
int opPos,
- XPathExecutionContext& executionContext) const;
+ XPathExecutionContext& executionContext) const
+ {
+ return executeMore(context, opPos + 2, executionContext);
+ }
/**
* Add the strings for the target element to a vector of strings.
@@ -440,20 +443,6 @@
int opPos,
XPathExecutionContext& executionContext) const;
- /**
- * Execute a step in a location path. This must be implemented
- * by a derived class of XPath (or don't call at all
- * from the derived implementation of locationPath()).
- * @param context The current source tree context node.
- * @param opPos The current position in the m_opMap array.
- * @return a node-set.
- */
- MutableNodeRefList*
- step(
- XalanNode* context,
- int opPos,
- XPathExecutionContext& executionContext) const;
-
protected:
/**
@@ -706,7 +695,10 @@
group(
XalanNode* context,
int opPos,
- XPathExecutionContext& executionContext) const;
+ XPathExecutionContext& executionContext) const
+ {
+ return executeMore(context, opPos + 2, executionContext);
+ }
/**
* Get a literal value.
@@ -730,7 +722,10 @@
arg(
XalanNode* context,
int opPos,
- XPathExecutionContext& executionContext) const;
+ XPathExecutionContext& executionContext) const
+ {
+ return executeMore(context, opPos + 2, executionContext);
+ }
/**
* Execute a location path.
@@ -760,11 +755,17 @@
const XObjectPtr
extfunction(
XalanNode*
context,
- int
opPos,
+ int
/* opPos */,
const XalanDOMString&
theNamespace,
const XalanDOMString&
functionName,
const Function::XObjectArgVectorType& argVec,
- XPathExecutionContext&
executionContext) const;
+ XPathExecutionContext&
executionContext) const
+ {
+ return executionContext.extFunction(theNamespace,
+
functionName,
+
context,
+
argVec);
+ }
/**
* Setup for and run a function.
@@ -784,7 +785,10 @@
int
opPos,
int
funcID,
const Function::XObjectArgVectorType& argVec,
- XPathExecutionContext&
executionContext) const;
+ XPathExecutionContext&
executionContext) const
+ {
+ return s_functions[funcID].execute(executionContext, context, opPos,
argVec);
+ }
double
getNumericOperand(
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]