Преглед на файлове

2005-01-18 Atsushi Enomoto <[email protected]>

	* XmlNode.cs,
	  XmlAttribute.cs,
	  XmlAttributeCollection.cs :
	  Now reuse parentNode field for XmlAttribute.OwnerElement and
	  reduce class allocation size.
	* XmlNameEntry.cs :
	  New class that represents a name triplet.
	  XmlNameEntryCache.cs :
	  New type to cache name entries.
	* XmlAttribute.cs,
	  XmlElement.cs :
	  Replace name strings with name entry and save class allocation size.
	  XmlDocument.cs :
	  Add name entry cache field to document and reuse name entries that 
	  are already allocated.



svn path=/trunk/mcs/; revision=39086
Atsushi Eno преди 21 години
родител
ревизия
e65be58d88

+ 18 - 0
mcs/class/System.XML/System.Xml/ChangeLog

@@ -1,3 +1,21 @@
+2005-01-18  Atsushi Enomoto <[email protected]>
+
+	* XmlNode.cs,
+	  XmlAttribute.cs,
+	  XmlAttributeCollection.cs :
+	  Now reuse parentNode field for XmlAttribute.OwnerElement and
+	  reduce class allocation size.
+	* XmlNameEntry.cs :
+	  New class that represents a name triplet.
+	  XmlNameEntryCache.cs :
+	  New type to cache name entries.
+	* XmlAttribute.cs,
+	  XmlElement.cs :
+	  Replace name strings with name entry and save class allocation size.
+	  XmlDocument.cs :
+	  Add name entry cache field to document and reuse name entries that 
+	  are already allocated.
+
 2005-01-17  Atsushi Enomoto <[email protected]>
 
 	* XmlNode.cs, XmlAttribute.cs : reverted the previous patch. It broke

+ 17 - 26
mcs/class/System.XML/System.Xml/XmlAttribute.cs

@@ -44,11 +44,8 @@ namespace System.Xml
 	{
 		#region Fields
 
-		private string localName;
-		private string namespaceURI;
-		private string prefix;
+		private XmlNameEntry name;
 		internal bool isDefault;
-		private XmlElement ownerElement;
 #if NET_2_0
 		private IXmlSchemaInfo schemaInfo;
 #endif
@@ -94,15 +91,12 @@ namespace System.Xml
 			else if (!XmlChar.IsName (localName))
 				throw new ArgumentException ("Invalid attribute local name.");
 
-			if (atomizedNames) {
-				this.prefix = prefix;
-				this.localName = localName;
-				this.namespaceURI = namespaceURI;
-			} else {
-				this.prefix = doc.NameTable.Add (prefix);
-				this.localName = doc.NameTable.Add (localName);
-				this.namespaceURI = doc.NameTable.Add (namespaceURI);
+			if (!atomizedNames) {
+				prefix = doc.NameTable.Add (prefix);
+				localName = doc.NameTable.Add (localName);
+				namespaceURI = doc.NameTable.Add (namespaceURI);
 			}
+			name = doc.NameCache.Add (prefix, localName, namespaceURI, true);
 		}
 
 		#endregion
@@ -144,19 +138,19 @@ namespace System.Xml
 
 		public override string LocalName {
 			get {
-				return localName;
+				return name.LocalName;
 			}
 		}
 
 		public override string Name {
 			get { 
-				return prefix != String.Empty ? OwnerDocument.NameTable.Add (prefix + ":" + localName) : localName; 
+				return name.Prefix != String.Empty ? OwnerDocument.NameTable.Add (name.Prefix + ":" + name.LocalName) : name.LocalName;
 			}
 		}
 
 		public override string NamespaceURI {
 			get {
-				return namespaceURI;
+				return name.NS;
 			}
 		}
 
@@ -179,7 +173,7 @@ namespace System.Xml
 		}
 
 		public virtual XmlElement OwnerElement {
-			get { return ownerElement; }
+			get { return AttributeOwnerElement; }
 		}
 
 		public override XmlNode ParentNode {
@@ -201,14 +195,16 @@ namespace System.Xml
 					throw new XmlException ("This node is readonly.");
 				if (!XmlChar.IsNCName (value))
 					throw new ArgumentException ("Specified name is not a valid NCName: " + value);
-				if (prefix == "xmlns" && value != "xmlns")
+				if (name.Prefix == "xmlns" && value != "xmlns")
 					throw new ArgumentException ("Cannot bind to the reserved namespace.");
 
-				prefix = OwnerDocument.NameTable.Add (value);
+				value = OwnerDocument.NameTable.Add (value);
+				name = OwnerDocument.NameCache.Add (value,
+					name.LocalName, name.NS, true);
 			}
 			
 			get {
-				return prefix;
+				return name.Prefix;
 			}
 		}
 
@@ -270,7 +266,7 @@ namespace System.Xml
 
 		public override XmlNode CloneNode (bool deep)
 		{
-			XmlNode node = new XmlAttribute (prefix, localName, namespaceURI,
+			XmlNode node = new XmlAttribute (name.Prefix, name.LocalName, name.NS,
 							 OwnerDocument, true, false);
 			if (deep) {
 				for (int i = 0; i < ChildNodes.Count; i++)
@@ -287,11 +283,6 @@ namespace System.Xml
 			isDefault = true;
 		}
 
-		// Parent of XmlAttribute must be null
-		internal void SetOwnerElement (XmlElement el) {
-			ownerElement = el;
-		}
-
 		public override void WriteContentTo (XmlWriter w)
 		{
 			for (int i = 0; i < ChildNodes.Count; i++)
@@ -300,7 +291,7 @@ namespace System.Xml
 
 		public override void WriteTo (XmlWriter w)
 		{
-			w.WriteStartAttribute (prefix, localName, namespaceURI);
+			w.WriteStartAttribute (name.Prefix, name.LocalName, name.NS);
 			WriteContentTo (w);
 			w.WriteEndAttribute ();
 		}

+ 2 - 2
mcs/class/System.XML/System.Xml/XmlAttributeCollection.cs

@@ -218,7 +218,7 @@ namespace System.Xml
 				attr.SetDefault ();
 				this.SetNamedItem (attr);
 			}
-			retAttr.SetOwnerElement (null);
+			retAttr.AttributeOwnerElement = null;
 			return retAttr;
 		}
 
@@ -260,7 +260,7 @@ namespace System.Xml
 
 			ownerElement.OwnerDocument.onNodeInserting (node, ownerElement);
 
-			attr.SetOwnerElement (ownerElement);
+			attr.AttributeOwnerElement = ownerElement;
 			XmlNode n = AdjustIdenticalAttributes (node as XmlAttribute, base.SetNamedItem (node, -1, false));
 
 			ownerElement.OwnerDocument.onNodeInserted (node, ownerElement);

+ 5 - 0
mcs/class/System.XML/System.Xml/XmlDocument.cs

@@ -60,6 +60,7 @@ namespace System.Xml
 		bool preserveWhitespace = false;
 		XmlResolver resolver;
 		Hashtable idTable = new Hashtable ();
+		XmlNameEntryCache nameCache = new XmlNameEntryCache ();
 #if NET_2_0
 		XmlSchemaSet schemas;
 #endif
@@ -181,6 +182,10 @@ namespace System.Xml
 			get { return "#document"; }
 		}
 
+		internal XmlNameEntryCache NameCache {
+			get { return nameCache; }
+		}
+
 		public XmlNameTable NameTable {
 			get { return nameTable; }
 		}

+ 17 - 19
mcs/class/System.XML/System.Xml/XmlElement.cs

@@ -47,9 +47,8 @@ namespace System.Xml
 		#region Fields
 
 		private XmlAttributeCollection attributes;
-		private string localName;
-		private string namespaceURI;
-		private string prefix;
+		private XmlNameEntry name;
+
 		private bool isNotEmpty;
 #if NET_2_0
 		IXmlSchemaInfo schemaInfo;
@@ -76,15 +75,12 @@ namespace System.Xml
 		{
 			XmlConvert.VerifyName (localName);
 
-			if (atomizedNames) {
-				this.prefix = prefix;
-				this.localName = localName;
-				this.namespaceURI = namespaceURI;
-			} else {
-				this.prefix = doc.NameTable.Add (prefix);
-				this.localName = doc.NameTable.Add (localName);
-				this.namespaceURI = doc.NameTable.Add (namespaceURI);
+			if (!atomizedNames) {
+				prefix = doc.NameTable.Add (prefix);
+				localName = doc.NameTable.Add (localName);
+				namespaceURI = doc.NameTable.Add (namespaceURI);
 			}
+			name = doc.NameCache.Add (prefix, localName, namespaceURI, true);
 
 //			attributes = new XmlAttributeCollection (this);
 
@@ -174,20 +170,20 @@ namespace System.Xml
 		}
 
 		public override string LocalName {
-			get { return localName; }
+			get { return name.LocalName; }
 		}
 
 		public override string Name {
 			get {
-				if (prefix == String.Empty || prefix == null)
-					return localName;
+				if (name.Prefix == String.Empty || name.Prefix == null)
+					return name.LocalName;
 				else
-					return OwnerDocument.NameTable.Add (prefix + ":" + localName);
+					return OwnerDocument.NameTable.Add (name.Prefix + ":" + name.LocalName);
 			}
 		}
 
 		public override string NamespaceURI {
-			get { return namespaceURI; }
+			get { return name.NS; }
 		}
 
 		// Why is this override?
@@ -216,14 +212,16 @@ namespace System.Xml
 		}
 
 		public override string Prefix {
-			get { return prefix; }
+			get { return name.Prefix; }
 			set {
 				if (IsReadOnly)
 					throw new XmlException ("This node is readonly.");
 				if (!XmlChar.IsNCName (value))
 					throw new ArgumentException ("Specified name is not a valid NCName: " + value);
 
-				prefix = OwnerDocument.NameTable.Add (value);
+				value = OwnerDocument.NameTable.Add (value);
+				name = OwnerDocument.NameCache.Add (value,
+					name.LocalName, name.NS, true);
 			}
 		}
 
@@ -241,7 +239,7 @@ namespace System.Xml
 		public override XmlNode CloneNode (bool deep)
 		{
 			XmlElement node = new XmlElement (
-				prefix, localName, namespaceURI, OwnerDocument, true);
+				name.Prefix, name.LocalName, name.NS, OwnerDocument, true);
 
 			for (int i = 0; i < Attributes.Count; i++)
 				node.SetAttributeNode ((XmlAttribute) 

+ 49 - 0
mcs/class/System.XML/System.Xml/XmlNameEntry.cs

@@ -0,0 +1,49 @@
+//
+// System.Xml.XmlNameEntry.cs
+//
+// Authors:
+//	Atsushi Enomoto  <[email protected]>
+//
+// (C) 2005 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace System.Xml
+{
+	internal class XmlNameEntry
+	{
+		public XmlNameEntry (string prefix, string local, string ns)
+		{
+			Prefix = prefix;
+			LocalName = local;
+			NS = ns;
+		}
+
+		public readonly string Prefix;
+		public readonly string LocalName;
+		public readonly string NS;
+	}
+}

+ 93 - 0
mcs/class/System.XML/System.Xml/XmlNameEntryCache.cs

@@ -0,0 +1,93 @@
+//
+// System.Xml.XmlNameEntryCache.cs
+//
+// Authors:
+//	Atsushi Enomoto  <[email protected]>
+//
+// (C) 2005 Novell, Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+
+namespace System.Xml
+{
+	internal class XmlNameEntryCache
+	{
+		ArrayList list = new ArrayList ();
+		int insertAt = 0;
+
+		public XmlNameEntryCache ()
+		{
+		}
+
+		public XmlNameEntry Add (string prefix, string local, string ns,
+			bool atomic)
+		{
+			XmlNameEntry e = GetInternal (prefix, local, ns, atomic);
+			if (e == null) {
+				e = new XmlNameEntry (prefix, local, ns);
+				// Let's just limit the maximum pool size.
+				if (list.Count < 1000)
+					list.Add (e);
+				else {
+					if (insertAt == 1000)
+						insertAt = 0;
+					list [insertAt++] = e;
+				}
+			}
+			return e;
+		}
+
+		public XmlNameEntry Get (string prefix, string local, string ns,
+			bool atomic)
+		{
+			XmlNameEntry e = GetInternal (prefix, local, ns, atomic);
+			return e;
+		}
+
+		private XmlNameEntry GetInternal (string prefix, string local,
+			string ns, bool atomic)
+		{
+			if (atomic) {
+				for (int i = 0; i < list.Count; i++) {
+					XmlNameEntry e = (XmlNameEntry) list [i];
+					if (Object.ReferenceEquals (e.Prefix, prefix) &&
+						Object.ReferenceEquals (e.LocalName, local) &&
+						Object.ReferenceEquals (e.NS, ns))
+						return e;
+				}
+			} else {
+				for (int i = 0; i < list.Count; i++) {
+					XmlNameEntry e = (XmlNameEntry) list [i];
+					if (e.Prefix == prefix &&
+						e.LocalName == local &&
+						e.NS == ns)
+						return e;
+				}
+			}
+			return null;
+		}
+	}
+}

+ 6 - 0
mcs/class/System.XML/System.Xml/XmlNode.cs

@@ -698,6 +698,12 @@ namespace System.Xml
 			return oldChild;
 		}
 
+		// WARNING: don't use this member outside XmlAttribute nodes.
+		internal XmlElement AttributeOwnerElement {
+			get { return (XmlElement) parentNode; }
+			set { parentNode = value; }
+		}
+
 		internal void SearchDescendantElements (string name, bool matchAll, ArrayList list)
 		{
 			for (int i = 0; i < ChildNodes.Count; i++) {