dbertoni    00/07/21 12:38:31

  Modified:    c/src/XercesParserLiaison XercesBridgeNavigator.cpp
                        XercesBridgeNavigator.hpp XercesDocumentBridge.cpp
                        XercesDocumentBridge.hpp
  Log:
  Experimental changes to cache nodes for increased performance.
  
  Revision  Changes    Path
  1.2       +81 -7     
xml-xalan/c/src/XercesParserLiaison/XercesBridgeNavigator.cpp
  
  Index: XercesBridgeNavigator.cpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XercesParserLiaison/XercesBridgeNavigator.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XercesBridgeNavigator.cpp 2000/04/11 14:39:29     1.1
  +++ XercesBridgeNavigator.cpp 2000/07/21 19:38:31     1.2
  @@ -69,15 +69,32 @@
   
   
   
  +// I'm using this to distinguish between null nodes, which are valid, and
  +// an uninitialized cached node address.  This is probably bogus, and I'll
  +// probably just change this to 0, but this is experimental anyway...
  +XalanNode* const     invalidNodeAddress = reinterpret_cast<XalanNode*>(1);
  +
  +
  +
   XercesBridgeNavigator::XercesBridgeNavigator(XercesDocumentBridge*   
theOwnerDocument) :
  -     m_ownerDocument(theOwnerDocument)
  +     m_ownerDocument(theOwnerDocument),
  +     m_parentNode(invalidNodeAddress),
  +     m_previousSibling(invalidNodeAddress),
  +     m_nextSibling(invalidNodeAddress),
  +     m_firstChild(invalidNodeAddress),
  +     m_lastChild(invalidNodeAddress)
   {
   }
   
   
   
   XercesBridgeNavigator::XercesBridgeNavigator(const XercesBridgeNavigator&    
theSource) :
  -     m_ownerDocument(theSource.m_ownerDocument)
  +     m_ownerDocument(theSource.m_ownerDocument),
  +     m_parentNode(theSource.m_parentNode),
  +     m_previousSibling(theSource.m_previousSibling),
  +     m_nextSibling(theSource.m_nextSibling),
  +     m_firstChild(theSource.m_firstChild),
  +     m_lastChild(theSource.m_lastChild)
   {
   }
   
  @@ -89,6 +106,18 @@
   
   
   
  +void
  +XercesBridgeNavigator::clearCachedNodes()
  +{
  +     m_parentNode = invalidNodeAddress;
  +     m_previousSibling = invalidNodeAddress;
  +     m_nextSibling = invalidNodeAddress;
  +     m_firstChild = invalidNodeAddress;
  +     m_lastChild = invalidNodeAddress;
  +}
  +
  +
  +
   XercesDocumentBridge*
   XercesBridgeNavigator::getOwnerDocument() const
   {
  @@ -132,7 +161,16 @@
   XalanNode*
   XercesBridgeNavigator::getParentNode(const DOM_Node& theXercesNode) const
   {
  -     return m_ownerDocument->mapNode(theXercesNode.getParentNode());
  +     if (m_parentNode == invalidNodeAddress)
  +     {
  +#if defined(XALAN_NO_MUTABLE)
  +             ((XercesBridgeNavigator*)this)->m_parentNode = 
m_ownerDocument->mapNode(theXercesNode.getParentNode());
  +#else
  +             m_parentNode = 
m_ownerDocument->mapNode(theXercesNode.getParentNode());
  +#endif
  +     }
  +
  +     return m_parentNode;
   }
   
   
  @@ -140,7 +178,16 @@
   XalanNode*
   XercesBridgeNavigator::getPreviousSibling(const DOM_Node&    theXercesNode) 
const
   {
  -     return m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
  +     if (m_previousSibling == invalidNodeAddress)
  +     {
  +#if defined(XALAN_NO_MUTABLE)
  +             ((XercesBridgeNavigator*)this)->m_previousSibling = 
m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
  +#else
  +             m_previousSibling = 
m_ownerDocument->mapNode(theXercesNode.getPreviousSibling());
  +#endif
  +     }
  +
  +     return m_previousSibling;
   }
   
   
  @@ -148,7 +195,16 @@
   XalanNode*
   XercesBridgeNavigator::getNextSibling(const DOM_Node&        theXercesNode) 
const
   {
  -     return m_ownerDocument->mapNode(theXercesNode.getNextSibling());
  +     if (m_nextSibling == invalidNodeAddress)
  +     {
  +#if defined(XALAN_NO_MUTABLE)
  +             ((XercesBridgeNavigator*)this)->m_nextSibling = 
m_ownerDocument->mapNode(theXercesNode.getNextSibling());
  +#else
  +             m_nextSibling = 
m_ownerDocument->mapNode(theXercesNode.getNextSibling());
  +#endif
  +     }
  +
  +     return m_nextSibling;
   }
   
   
  @@ -156,7 +212,16 @@
   XalanNode*
   XercesBridgeNavigator::getFirstChild(const DOM_Node& theXercesNode) const
   {
  -     return m_ownerDocument->mapNode(theXercesNode.getFirstChild());
  +     if (m_firstChild == invalidNodeAddress)
  +     {
  +#if defined(XALAN_NO_MUTABLE)
  +             ((XercesBridgeNavigator*)this)->m_firstChild = 
m_ownerDocument->mapNode(theXercesNode.getFirstChild());
  +#else
  +             m_firstChild = 
m_ownerDocument->mapNode(theXercesNode.getFirstChild());
  +#endif
  +     }
  +
  +     return m_firstChild;
   }
   
   
  @@ -164,7 +229,16 @@
   XalanNode*
   XercesBridgeNavigator::getLastChild(const DOM_Node&  theXercesNode) const
   {
  -     return m_ownerDocument->mapNode(theXercesNode.getLastChild());
  +     if (m_lastChild == invalidNodeAddress)
  +     {
  +#if defined(XALAN_NO_MUTABLE)
  +             ((XercesBridgeNavigator*)this)->m_lastChild = 
m_ownerDocument->mapNode(theXercesNode.getLastChild());
  +#else
  +             m_lastChild = 
m_ownerDocument->mapNode(theXercesNode.getLastChild());
  +#endif
  +     }
  +
  +     return m_lastChild;
   }
   
   
  
  
  
  1.3       +16 -3     
xml-xalan/c/src/XercesParserLiaison/XercesBridgeNavigator.hpp
  
  Index: XercesBridgeNavigator.hpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XercesParserLiaison/XercesBridgeNavigator.hpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XercesBridgeNavigator.hpp 2000/05/03 18:39:26     1.2
  +++ XercesBridgeNavigator.hpp 2000/07/21 19:38:31     1.3
  @@ -90,9 +90,9 @@
        virtual
        ~XercesBridgeNavigator();
   
  -     XercesBridgeNavigator&
  -     operator=(const XercesBridgeNavigator&  theRHS);
   
  +     void
  +     clearCachedNodes();
   
        virtual XercesDocumentBridge*
        getOwnerDocument() const;
  @@ -163,11 +163,24 @@
   private:
   
        // Not implemented...
  +//   XercesBridgeNavigator&
  +//   operator=(const XercesBridgeNavigator&  theRHS);
  +
        bool
        operator==(const XercesBridgeNavigator& theRHS) const;
   
        // Data members...
  -     XercesDocumentBridge* const             m_ownerDocument;
  +     XercesDocumentBridge*   m_ownerDocument;
  +
  +     mutable XalanNode*              m_parentNode;
  +
  +     mutable XalanNode*              m_previousSibling;
  +
  +     mutable XalanNode*              m_nextSibling;
  +
  +     mutable XalanNode*              m_firstChild;
  +
  +     mutable XalanNode*              m_lastChild;
   };
   
   
  
  
  
  1.9       +153 -34   
xml-xalan/c/src/XercesParserLiaison/XercesDocumentBridge.cpp
  
  Index: XercesDocumentBridge.cpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XercesParserLiaison/XercesDocumentBridge.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XercesDocumentBridge.cpp  2000/06/23 22:00:23     1.8
  +++ XercesDocumentBridge.cpp  2000/07/21 19:38:31     1.9
  @@ -108,6 +108,7 @@
                                          m_navigator),
        m_nodeMap(),
        m_domImplementation(new 
XercesDOMImplementationBridge(theXercesDocument.getImplementation())),
  +     m_navigators(),
        m_nodes(),
        m_doctype(0)
   {
  @@ -118,24 +119,12 @@
        // Put ourself into the node map, and don't assign an index...
        m_nodeMap.addAssociation(m_xercesDocument, this, false);
   
  -     // Try to build the doctype...
  -     DOM_DocumentType        theDoctype = theXercesDocument.getDoctype();
  -
  -     if (theDoctype.isNull() == false)
  -     {
  -             m_doctype = new XercesDocumentTypeBridge(theDoctype, 
m_navigator);
  +     m_doctype = buildDocumentTypeBridge();
   
  -             // Add it to the node map...
  -             m_nodeMap.addAssociation(theDoctype, m_doctype, false);
  -
  -             m_nodes.insert(m_doctype);
  -     }
  -
        if (buildBridge == true)
        {
                // OK, let's build the nodes.  This makes things
                // thread-safe, so the document can be shared...
  -
                buildBridgeNodes();
        }
   }
  @@ -144,15 +133,7 @@
   
   XercesDocumentBridge::~XercesDocumentBridge()
   {
  -#if !defined(XALAN_NO_NAMESPACES)
  -     using std::for_each;
  -#endif
  -
  -     // m_bridgeMap contains all of the nodes that
  -     // are still alive...
  -     for_each(m_nodes.begin(),
  -                      m_nodes.end(),
  -                      DeleteFunctor<XalanNode>());
  +     destroyBridge();
   }
   
   
  @@ -266,7 +247,75 @@
   
   
   
  +class ClearCacheFunctor
  +{
  +public:
  +
  +     void
  +     operator()(XercesBridgeNavigator&       theNavigator)
  +     {
  +             theNavigator.clearCachedNodes();
  +     }
  +};
  +
  +
  +
  +void
  +XercesDocumentBridge::clearCachedNodes()
  +{
  +#if !defined(XALAN_NO_NAMESPACES)
  +     using std::for_each;
  +#endif
  +     // m_bridgeMap contains all of the nodes that
  +     // are still alive...
  +     for_each(m_navigators.begin(),
  +                      m_navigators.end(),
  +                      ClearCacheFunctor());
  +
  +}
  +
  +
  +
  +void
  +XercesDocumentBridge::destroyBridge()
  +{
  +#if !defined(XALAN_NO_NAMESPACES)
  +     using std::for_each;
  +#endif
  +     // Set this to null, since it will be deleted
  +     // by the next for_each...
  +     m_doctype = 0;
  +
  +     // m_bridgeMap contains all of the nodes that
  +     // are still alive...
  +     for_each(m_nodes.begin(),
  +                      m_nodes.end(),
  +                      DeleteFunctor<XalanNode>());
  +
  +     // Clear everything out...
  +     m_nodes.clear();
  +
  +     m_navigators.clear();
  +
  +     m_nodeMap.clear();
  +}
  +
  +
  +
   void
  +XercesDocumentBridge::rebuildBridge()
  +{
  +     destroyBridge();
  +
  +     // Create the doctype...
  +     m_doctype = buildDocumentTypeBridge();
  +
  +     buildBridgeNodes();
  +}
  +
  +
  +
  +void
   XercesDocumentBridge::buildBridgeNodes()
   {
        // First, build any children of the document...
  @@ -286,7 +335,7 @@
   
        if (theDocumentElement != 0)
        {
  -             NullTreeWalker  theTreeWalker;
  +             NullTreeWalker  theTreeWalker(true);
   
                theTreeWalker.traverse(theDocumentElement, this);
        }
  @@ -297,10 +346,9 @@
   XercesElementBridge*
   XercesDocumentBridge::createBridgeNode(const DOM_Element&    theXercesNode) 
const
   {
  -
        XercesElementBridge* const      theBridge =
                new XercesElementBridge(theXercesNode,
  -                                                             m_navigator);
  +                                                             
pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -317,7 +365,7 @@
   {
        XercesDocumentFragmentBridge* const             theBridge =
                new XercesDocumentFragmentBridge(theXercesNode,
  -                                                                             
 m_navigator);
  +                                                                             
 pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -334,7 +382,7 @@
   {
        XercesTextBridge* const         theBridge =
                new XercesTextBridge(theXercesNode,
  -                                                             m_navigator);
  +                                                      pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -351,7 +399,7 @@
   {
        XercesCommentBridge* const      theBridge =
                new XercesCommentBridge(theXercesNode,
  -                                                             m_navigator);
  +                                                             
pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -368,7 +416,7 @@
   {
        XercesCDATASectionBridge* const         theBridge =
                new XercesCDATASectionBridge(theXercesNode,
  -                                                                      
m_navigator);
  +                                                                      
pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -385,7 +433,7 @@
   {
        XercesProcessingInstructionBridge* const        theBridge =
                new XercesProcessingInstructionBridge(theXercesNode,
  -                                                                             
          m_navigator);
  +                                                                             
          pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -402,7 +450,7 @@
   {
        XercesAttrBridge* const         theBridge =
                new XercesAttrBridge(theXercesNode,
  -                                                             m_navigator);
  +                                                      pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -419,7 +467,7 @@
   {
        XercesEntityBridge* const       theBridge =
                new XercesEntityBridge(theXercesNode,
  -                                                             m_navigator);
  +                                                        pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -436,7 +484,7 @@
   {
        XercesEntityReferenceBridge* const      theBridge =
                new XercesEntityReferenceBridge(theXercesNode,
  -                                                                             
m_navigator);
  +                                                                             
pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -453,7 +501,7 @@
   {
        XercesNotationBridge* const             theBridge =
                new XercesNotationBridge(theXercesNode,
  -                                                              m_navigator);
  +                                                              
pushNavigator());
   
        m_nodes.insert(theBridge);
   
  @@ -518,6 +566,35 @@
   
   
   
  +XercesDocumentTypeBridge*
  +XercesDocumentBridge::buildDocumentTypeBridge() const
  +{
  +     XercesDocumentTypeBridge*       theResult = 0;
  +
  +     // Try to build the doctype...
  +     DOM_DocumentType        theDoctype = m_xercesDocument.getDoctype();
  +
  +     if (theDoctype.isNull() == false)
  +     {
  +             theResult = new XercesDocumentTypeBridge(theDoctype, 
pushNavigator());
  +#if defined(XALAN_NO_MUTABLE)
  +             // Add it to the node map...
  +             
((XercesDocumentBridge*)this)->m_nodeMap.addAssociation(theDoctype, theResult, 
false);
  +
  +             ((XercesDocumentBridge*)this)->m_nodes.insert(theResult);
  +#else
  +             // Add it to the node map...
  +             m_nodeMap.addAssociation(theDoctype, theResult, false);
  +
  +             m_nodes.insert(theResult);
  +#endif
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
   // The rest of these are the standard DOM interfaces...
   
   XalanDOMString
  @@ -953,6 +1030,31 @@
   XalanDocumentType*
   XercesDocumentBridge::getDoctype() const
   {
  +     if (m_doctype == 0)
  +     {
  +             // Try to build the doctype...
  +             DOM_DocumentType        theDoctype = 
m_xercesDocument.getDoctype();
  +
  +             if (theDoctype.isNull() == false)
  +             {
  +#if defined(XALAN_NO_MUTABLE)
  +                     ((XercesDocumentBridge*)this)->m_doctype = new 
XercesDocumentTypeBridge(theDoctype, pushNavigator());
  +
  +                     // Add it to the node map...
  +                     
((XercesDocumentBridge*)this)->m_nodeMap.addAssociation(theDoctype, m_doctype, 
false);
  +
  +                     
((XercesDocumentBridge*)this)->m_nodes.insert(m_doctype);
  +#else
  +                     m_doctype = new XercesDocumentTypeBridge(theDoctype, 
pushNavigator());
  +
  +                     // Add it to the node map...
  +                     m_nodeMap.addAssociation(theDoctype, m_doctype, false);
  +
  +                     m_nodes.insert(m_doctype);
  +#endif
  +             }
  +     }
  +
        return m_doctype;
   }
   
  @@ -989,6 +1091,9 @@
                        bool            deep)
   {
        // $$$ToDo: Fix this....
  +     // The problem is that we must get the Xerces node that corresponds to 
the
  +     // importedNode parameter.  We could assume that it is indeed a node 
from
  +     // another XercesDocumentBridge, but I'm not sure that we should do 
that.
        throw 
XercesDOMException(XercesDOMException::NO_MODIFICATION_ALLOWED_ERR);
   
        return 0;
  @@ -1195,3 +1300,17 @@
   
        return theNewNode;
   }
  +
  +
  +
  +const XercesBridgeNavigator&
  +XercesDocumentBridge::pushNavigator() const
  +{
  +     XercesDocumentBridge* const             This =
  +             const_cast<XercesDocumentBridge*>(this);
  +
  +     m_navigators.push_back(XercesBridgeNavigator(This));
  +
  +     return m_navigators.back();
  +}
  +
  
  
  
  1.4       +43 -1     
xml-xalan/c/src/XercesParserLiaison/XercesDocumentBridge.hpp
  
  Index: XercesDocumentBridge.hpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/c/src/XercesParserLiaison/XercesDocumentBridge.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XercesDocumentBridge.hpp  2000/06/07 18:13:56     1.3
  +++ XercesDocumentBridge.hpp  2000/07/21 19:38:31     1.4
  @@ -63,6 +63,7 @@
   
   
   
  +#include <deque>
   #include <memory>
   #include <set>
   
  @@ -272,6 +273,34 @@
   
        // These are some special interfaces to manage relationships between
        // our nodes and Xerces nodes.
  +
  +     /**
  +      * Destroy the entire bridge structure that connects
  +      * the Xerces document to this XercesDocumentBridge
  +      * instance.  This will invalidate any pointers to
  +      * any nodes in the document (except, of course, the
  +      * document itself).
  +      */
  +     void
  +     destroyBridge();
  +
  +     /**
  +      * Rebuild the entire bridge structure that connects
  +      * the Xerces document to this XercesDocumentBridge
  +      * instance.  This destroys the bridge before
  +      * rebuilding.
  +      */
  +     void
  +     rebuildBridge();
  +
  +     /**
  +      * Clears any node relationships that may have been
  +      * cached.  This should be done if the document is
  +      * modified in any way.
  +      */
  +     void
  +     clearCachedNodes();
  +
        XalanNode*
        mapNode(const DOM_Node&         theXercesNode) const;
   
  @@ -343,6 +372,10 @@
                        const DOM_Node&         theXercesNode,
                        bool                            deep);
   
  +     // Convenience function to build the Doctype node...
  +     XercesDocumentTypeBridge*
  +     buildDocumentTypeBridge() const;
  +
        // Factory methods for our implementation nodes...
        XalanNode*
        createBridgeNode(const DOM_Node&        theXercesNode) const;
  @@ -377,6 +410,9 @@
        XercesNotationBridge*
        createBridgeNode(const DOM_Notation&    theXercesNode) const;
   
  +     const XercesBridgeNavigator&
  +     pushNavigator() const;
  +
        // $$$ ToDo: This is because DOM_Document::getElementById() is not
        // const...
        mutable DOM_Document                                    
m_xercesDocument;
  @@ -392,16 +428,22 @@
   #if defined(XALAN_NO_NAMESPACES)
        auto_ptr<XalanDOMImplementation>                m_domImplementation;
   
  +     typedef deque<XercesBridgeNavigator>    NavigatorBridgeVectorType;
  +
        typedef set<XalanNode*>                                 NodeSetType;
   #else
        std::auto_ptr<XalanDOMImplementation>   m_domImplementation;
   
  +     typedef std::deque<XercesBridgeNavigator>       
NavigatorBridgeVectorType;
  +
        typedef std::set<XalanNode*>                    NodeSetType;
   #endif
   
  +     mutable NavigatorBridgeVectorType               m_navigators;
  +
        mutable NodeSetType                                             m_nodes;
   
  -     XercesDocumentTypeBridge*                               m_doctype;
  +     mutable XercesDocumentTypeBridge*               m_doctype;
   };
   
   
  
  
  

Reply via email to