You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@locus.apache.org on 2000/07/21 21:38:32 UTC

cvs commit: xml-xalan/c/src/XercesParserLiaison XercesBridgeNavigator.cpp XercesBridgeNavigator.hpp XercesDocumentBridge.cpp XercesDocumentBridge.hpp

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;
   };