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]

Reply via email to