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