Author: jonpryor
Date: 2007-05-29 07:37:33 -0400 (Tue, 29 May 2007)
New Revision: 78109

Modified:
   trunk/monodoc/tools/ChangeLog
   trunk/monodoc/tools/monodocer.cs
Log:
        * monodocer.cs: Invert ECMA documentation importing -- instead of 
iterating
          over the monodoc XML and importing ECMA docs as encountered 
(randomly), 
          iterate over the ECMA docs in-order and access the monodoc types 
randomly.
          This significantly improves access as the ECMA docs are ~7.2MB in 
size,
          while the monodoc XML types 10's-100's of KB (randomly accessing a 
7.2 MB
          XML document == BAD; randomly accessing a several hundred KB document 
is
          better).  This cuts down a -type:System.Array import from ~4 minutes 
to
          < ~20s.  Alas, it appears to miss a few members as well, so it's not 
done.


Modified: trunk/monodoc/tools/ChangeLog
===================================================================
--- trunk/monodoc/tools/ChangeLog       2007-05-29 11:23:57 UTC (rev 78108)
+++ trunk/monodoc/tools/ChangeLog       2007-05-29 11:37:33 UTC (rev 78109)
@@ -1,3 +1,14 @@
+2007-05-29  Jonathan Pryor  <[EMAIL PROTECTED]>
+
+       * monodocer.cs: Invert ECMA documentation importing -- instead of 
iterating
+         over the monodoc XML and importing ECMA docs as encountered 
(randomly), 
+         iterate over the ECMA docs in-order and access the monodoc types 
randomly.
+         This significantly improves access as the ECMA docs are ~7.2MB in 
size,
+         while the monodoc XML types 10's-100's of KB (randomly accessing a 
7.2 MB
+         XML document == BAD; randomly accessing a several hundred KB document 
is
+         better).  This cuts down a -type:System.Array import from ~4 minutes 
to
+         < ~20s.  Alas, it appears to miss a few members as well, so it's not 
done.
+
 2007-05-19  Jonathan Pryor  <[EMAIL PROTECTED]>
 
        * monodocer.cs: Create diff(1)-friendly output for -importecmadocs.

Modified: trunk/monodoc/tools/monodocer.cs
===================================================================
--- trunk/monodoc/tools/monodocer.cs    2007-05-29 11:23:57 UTC (rev 78108)
+++ trunk/monodoc/tools/monodocer.cs    2007-05-29 11:37:33 UTC (rev 78109)
@@ -319,16 +319,44 @@
                        throw new InvalidOperationException("Error loading " + 
typefile + ": " + e.Message, e);
                }
                
+               XmlNode ecmaDocsType = GetEcmaDocsType (basefile);
                if (dest == null) {
-                       DoUpdateType2(basefile, type, typefile);
+                       DoUpdateType2(basefile, type, typefile, ecmaDocsType);
                } else if (dest == "-") {
-                       DoUpdateType2(basefile, type, null);
+                       DoUpdateType2(basefile, type, null, ecmaDocsType);
                } else {
-                       DoUpdateType2(basefile, type, dest + "/" + 
type.Namespace + "/" + typename2 + ".xml");
+                       DoUpdateType2(basefile, type, dest + "/" + 
type.Namespace + "/" + typename2 + ".xml", ecmaDocsType);
                }       
        }
 
+       private static XmlNode GetEcmaDocsType (XmlNode source)
+       {
+               return GetEcmaDocsMember ("//[EMAIL PROTECTED]"{0}\"]", source, 
"//Type/@FullName");
+       }
+
+       private static XmlNode GetEcmaDocsType (Type type)
+       {
+               return GetEcmaDocsMember ("//[EMAIL PROTECTED]"" + 
type.FullName + "\"]");
+       }
        
+       private static XmlNode GetEcmaDocsMember (string xpathFormat, XmlNode 
source, params string[] args)
+       {
+               if (ecmadocs == null)
+                       return null;
+               string [] nargs = new string [args.Length];
+               for (int i = 0; i < nargs.Length; ++i) {
+                       nargs [i] = source.SelectSingleNode (args [i]).Value;
+               }
+               return ecmadocs.SelectSingleNode (string.Format (xpathFormat, 
nargs));
+       }
+
+       private static XmlNode GetEcmaDocsMember (string xpath)
+       {
+               if (ecmadocs == null)
+                       return null;
+               return ecmadocs.SelectSingleNode (xpath);
+       }
+
        public static void DoUpdateNS(string ns, string nspath, string outpath) 
{
                Hashtable seenTypes = new Hashtable();
                Assembly assembly = assemblies [0];
@@ -352,7 +380,7 @@
                        }                       
 
                        seenTypes[type] = seenTypes;
-                       DoUpdateType2(basefile, type, outpath + "/" + 
file.Name);
+                       DoUpdateType2(basefile, type, outpath + "/" + 
file.Name, GetEcmaDocsType (basefile));
                }
                
                // Stub types not in the directory
@@ -361,7 +389,7 @@
                        if (type.Namespace != ns || seenTypes.ContainsKey(type))
                                continue;
 
-                       XmlElement td = StubType(type);
+                       XmlElement td = StubType(type, GetEcmaDocsType (type));
                        if (td == null) continue;
                        
                        Console.Error.WriteLine("New Type: " + type.FullName);
@@ -487,10 +515,10 @@
                                        throw new 
InvalidOperationException("Error loading " + typefile + ": " + e.Message, e);
                                }
                                
-                               DoUpdateType2(basefile, type, dest + "/" + 
type.Namespace + "/" + typename + ".xml");
+                               DoUpdateType2(basefile, type, dest + "/" + 
type.Namespace + "/" + typename + ".xml", GetEcmaDocsType (basefile));
                        } else {
                                // Stub
-                               XmlElement td = StubType(type);
+                               XmlElement td = StubType(type, GetEcmaDocsType 
(type));
                                if (td == null) continue;
                                
                                System.IO.DirectoryInfo dir = new 
System.IO.DirectoryInfo(dest + "/" + type.Namespace);
@@ -576,20 +604,21 @@
                }
        }
                
-       public static void DoUpdateType2(XmlDocument basefile, Type type, 
string output) {
+       public static void DoUpdateType2(XmlDocument basefile, Type type, 
string output, XmlNode ecmaDocsType) {
                Console.Error.WriteLine("Updating: " + type.FullName);
                
                Hashtable seenmembers = new Hashtable();
 
                // Update type metadata
-               UpdateType(basefile.DocumentElement, type, false);
+               UpdateType(basefile.DocumentElement, type, false, ecmaDocsType);
 
                // Update existing members.  Delete member nodes that no longer 
should be there,
                // and remember what members are already documented so we don't 
add them again.
                if (!ignoremembers) {
                        ArrayList todelete = new ArrayList ();
-                       foreach (XmlElement oldmember in 
basefile.SelectNodes("Type/Members/Member")) {
-                               MemberInfo oldmember2 = GetMember(type, 
oldmember);
+                       foreach (DocsNodeInfo info in GetMembers (basefile, 
type, ecmaDocsType)) {
+                               XmlElement oldmember  = info.Node;
+                               MemberInfo oldmember2 = info.Member;
                                string sig = oldmember2 != null ? 
MakeMemberSignature(oldmember2) : null;
                                
                                // Interface implementations and overrides are 
deleted from the docs
@@ -620,7 +649,7 @@
                                }
                                
                                // Update signature information
-                               UpdateMember(oldmember, oldmember2);
+                               UpdateMember(info);
                                
                                seenmembers[sig] = 1;
                        }
@@ -673,6 +702,41 @@
                WriteXml(basefile.DocumentElement, writer);
                writer.Close();
        }
+
+       private static 
+#if NET_1_0
+               IEnumerable
+#else
+               IEnumerable<DocsNodeInfo>
+#endif
+               GetMembers (XmlDocument basefile, Type type, XmlNode 
ecmaDocsType)
+       {
+               if (ecmadocs == null) {
+                       foreach (XmlElement oldmember in 
basefile.SelectNodes("Type/Members/Member"))
+                               yield return new DocsNodeInfo (oldmember, 
GetMember (type, oldmember));
+               }
+               else {
+                       foreach (XmlElement ecmaDocsMember in 
ecmaDocsType.SelectNodes ("Members/Member")) {
+                               string xp = GetXPathForMember (ecmaDocsMember);
+                               XmlElement oldmember = (XmlElement) 
basefile.SelectSingleNode (xp);
+                               MemberInfo m;
+                               if (oldmember == null) {
+                                       m = GetMember (type, ecmaDocsMember);
+                                       if (m == null) {
+                                               Console.Error.WriteLine ("Could 
not import ECMA docs for {1}'s `{0}': MemberInfo not found.",
+                                                               
ecmaDocsMember.SelectSingleNode ("[EMAIL PROTECTED]"C#\"]/@Value").Value, 
type.FullName);
+                                               continue;
+                                       }
+                                       oldmember = (XmlElement) CopyNode 
(ecmaDocsMember, basefile.SelectSingleNode ("/Types/Members"));
+                               }
+                               else
+                                       m = GetMember (type, oldmember);
+                               DocsNodeInfo node = new DocsNodeInfo 
(oldmember, m);
+                               node.EcmaDocs = ecmaDocsMember.SelectSingleNode 
("Docs");
+                               yield return node;
+                       }
+               }
+       }
        
        private static bool MemberDocsHaveUserContent(XmlElement e) {
                e = (XmlElement)e.SelectSingleNode("Docs");
@@ -776,14 +840,14 @@
        
        // CREATE A STUB DOCUMENTATION FILE     
 
-       public static XmlElement StubType(Type type) {
+       public static XmlElement StubType(Type type, XmlNode ecmaDocsType) {
                string typesig = MakeTypeSignature(type);
                if (typesig == null) return null; // not publicly visible
                
                XmlDocument doc = new XmlDocument();
                XmlElement root = doc.CreateElement("Type");
                
-               UpdateType(root, type, true);
+               UpdateType(root, type, true, ecmaDocsType);
 
                if (since != null) {
                        XmlNode docs = root.SelectSingleNode("Docs");
@@ -802,7 +866,7 @@
        
        // STUBBING/UPDATING FUNCTIONS
        
-       public static void UpdateType(XmlElement root, Type type, bool 
addmembers) {
+       public static void UpdateType(XmlElement root, Type type, bool 
addmembers, XmlNode ecmaDocsType) {
                root.SetAttribute("Name", GetDocTypeName (type));
                root.SetAttribute("FullName", GetDocTypeFullName (type));
 
@@ -948,7 +1012,9 @@
 #endif
        }
        
-       private static void UpdateMember(XmlElement me, MemberInfo mi) {        
+       private static void UpdateMember(DocsNodeInfo info) {   
+               XmlElement me = (XmlElement) info.Node;
+               MemberInfo mi = info.Member;
                WriteElementAttribute(me, "[EMAIL PROTECTED]'C#']", "Language", 
"C#");
                WriteElementAttribute(me, "[EMAIL PROTECTED]'C#']", "Value", 
MakeMemberSignature(mi));
 
@@ -962,7 +1028,8 @@
                if (mi is FieldInfo && GetFieldConstValue((FieldInfo)mi, out 
fieldValue))
                        WriteElementText(me, "MemberValue", fieldValue);
                
-               MakeDocNode (new DocsNodeInfo (WriteElement (me, "Docs"), mi));
+               info.Node = WriteElement (me, "Docs");
+               MakeDocNode (info);
        }
        
        private static bool GetFieldConstValue(FieldInfo field, out string 
value) {
@@ -1010,10 +1077,11 @@
                node.InnerText = value;
        }
 
-       private static void CopyNode (XmlNode source, XmlNode dest)
+       private static XmlNode CopyNode (XmlNode source, XmlNode dest)
        {
                XmlNode copy = dest.OwnerDocument.ImportNode (source, true);
                dest.AppendChild (copy);
+               return copy;
        }
 
        private static void WriteElementInitialText(XmlElement parent, string 
element, string value) {
@@ -1457,7 +1525,7 @@
                XmlElement me = doc.CreateElement("Member");
                me.SetAttribute("MemberName", GetMemberName (mi));
                
-               UpdateMember(me, mi);
+               UpdateMember(new DocsNodeInfo (me, mi));
 
                if (since != null) {
                        XmlNode docs = me.SelectSingleNode("Docs");
@@ -1544,6 +1612,17 @@
                public DocsNodeInfo (XmlElement node, Type type)
                        : this (node)
                {
+                       SetType (type);
+               }
+
+               public DocsNodeInfo (XmlElement node, MemberInfo member)
+                       : this (node)
+               {
+                       SetMemberInfo (member);
+               }
+
+               public void SetType (Type type)
+               {
                        GenericParameters = DocUtils.GetGenericArguments (type);
                        if (type.DeclaringType != null) {
                                Type[] declGenParams = 
DocUtils.GetGenericArguments (type.DeclaringType);
@@ -1563,14 +1642,13 @@
                                ReturnType = 
type.GetMethod("Invoke").ReturnType;
                        }
                        SetSlashDocs (type);
-                       SetEcmaDocs (type);
                }
 
-               public DocsNodeInfo (XmlElement node, MemberInfo member)
-                       : this (node)
+               public void SetMemberInfo (MemberInfo member)
                {
                        ReturnIsReturn = true;
                        AddRemarks = true;
+                       Member = member;
                        
                        if (member is MethodInfo || member is ConstructorInfo) {
                                Parameters = ((MethodBase) 
member).GetParameters ();
@@ -1596,58 +1674,18 @@
                        if (member.DeclaringType != null && 
member.DeclaringType.IsEnum)
                                AddRemarks = false;
                        SetSlashDocs (member);
-                       SetEcmaDocs (member);
                }
 
                private void SetSlashDocs (MemberInfo member)
                {
+                       if (slashdocs == null)
+                               return;
+
                        string slashdocsig = slashdocFormatter.GetDeclaration 
(member);
-                       if (slashdocs != null && slashdocsig != null)
+                       if (slashdocsig != null)
                                SlashDocs = slashdocs.SelectSingleNode 
("doc/members/[EMAIL PROTECTED]'" + slashdocsig + "']");
                }
 
-               private void SetEcmaDocs (MemberInfo member)
-               {
-                       if (ecmadocs == null)
-                               return;
-
-                       string xpath;
-
-                       if (member is Type) {
-                               xpath = "//[EMAIL PROTECTED]"" + 
GetDocTypeFullName ((Type) member)+ "\"]/Docs";
-                       }
-                       else {
-                               // Create e.g.:
-                               // //Members/[EMAIL 
PROTECTED]"CopyTo"]/Parameters[count(Parameter) = 2 
-                               //   and Parameter[1]/@Type="System.Array" and 
-                               //   Parameter[2]/@Type="System.Int64"]/../Docs'
-                               StringBuilder sb = new StringBuilder ();
-                               sb.Append ("//[EMAIL PROTECTED]"")
-                                       .Append (GetDocTypeFullName 
(member.DeclaringType))
-                                       .Append ("\"]");
-                               sb.Append ("/Members/[EMAIL PROTECTED]"");
-                               if (member is ConstructorInfo)
-                                       sb.Append (".ctor");
-                               else
-                                       sb.Append (GetMemberName (member));
-                               sb.Append ("\"]");
-                               if (member is MethodBase) {
-                                       sb.Append ("/Parameters[");
-                                       ParameterInfo[] parameters = 
((MethodBase) member).GetParameters ();
-                                       sb.Append ("count(Parameter) = 
").Append (parameters.Length);
-                                       for (int i = 0; i < parameters.Length; 
++i) {
-                                               sb.Append (" and 
Parameter[").Append (i+1).Append ("]/@Type=\"")
-                                                       .Append 
(GetDocTypeFullName (parameters [i].ParameterType))
-                                                       .Append ("\"");
-                                       }
-                                       sb.Append ("]/..");
-                               }
-                               sb.Append ("/Docs");
-                               xpath = sb.ToString ();
-                       }
-                       EcmaDocs = ecmadocs.SelectSingleNode (xpath);
-               }
-
                public Type ReturnType;
                public Type[] GenericParameters;
                public ParameterInfo[] Parameters;
@@ -1656,7 +1694,32 @@
                public bool AddRemarks = true;
                public XmlNode SlashDocs;
                public XmlNode EcmaDocs;
+               public MemberInfo Member;
        }
+
+       public static string GetXPathForMember (XmlNode member)
+       {
+               StringBuilder xpath = new StringBuilder ();
+               xpath.Append ("//[EMAIL PROTECTED]"")
+                       .Append (member.SelectSingleNode 
("../../@FullName").Value)
+                       .Append ("\"]/");
+               xpath.Append ("Members/[EMAIL PROTECTED]"")
+                       .Append (member.SelectSingleNode ("@MemberName").Value)
+                       .Append ("\"]");
+               XmlNodeList parameters = member.SelectNodes 
("Parameters/Parameter");
+               if (parameters.Count > 0) {
+                       xpath.Append ("/Parameters[count(Parameter) = ")
+                               .Append (parameters.Count);
+                       for (int i = 0; i < parameters.Count; ++i) {
+                               xpath.Append (" and Parameter [").Append 
(i+1).Append ("]/@Type=\"");
+                               xpath.Append (member.SelectSingleNode (
+                                                       "Parameters/Parameter[" 
+ (i+1) + "]/@Type").Value);
+                               xpath.Append ("\"");
+                       }
+                       xpath.Append ("]/..");
+               }
+               return xpath.ToString ();
+       }
 }
 
 static class DocUtils {

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to