private CompilableFile GetCompilableFileFromExtension(string filename) { string ext = Path.GetExtension(filename); CompilableFile cf = null; switch (ext) { case ".aspx": cf = new PageCompilableFile(); break; case ".ascx": cf = new UserControlCompilableFile(); break; } if (cf != null) { cf.Init(_context, filename); } return(cf); }
internal static CompilableFile[][] Split(IDictionary compilableFiles) { // First phase: compute levels in the dependency tree int totaldepth = 0; Hashtable depth = new Hashtable(); Stack stack = new Stack(); // compute depths foreach (CompilableFile cf in compilableFiles.Values) { stack.Push(cf); while (stack.Count > 0) { CompilableFile curnode = (CompilableFile)stack.Peek(); bool recurse = false; int maxdepth = 0; foreach (CompilableFile child in curnode.CompilableFileReferences) { if (depth.ContainsKey(child)) { if (maxdepth <= (int)depth[child]) { maxdepth = (int)depth[child] + 1; } else if ((int)depth[child] == -1) { throw new HttpException(child.FileName + " has a circular reference!"); } } else { recurse = true; stack.Push(child); } } if (recurse) { depth[curnode] = -1; // being computed; } else { stack.Pop(); depth[curnode] = maxdepth; if (totaldepth <= maxdepth) { totaldepth = maxdepth + 1; } } } } // drop into buckets by depth ArrayList[] codeLevel = new ArrayList[totaldepth]; for (IDictionaryEnumerator en = (IDictionaryEnumerator)depth.GetEnumerator(); en.MoveNext();) { int level = (int)en.Value; if (codeLevel[level] == null) { codeLevel[level] = new ArrayList(); } codeLevel[level].Add(en.Key); } // return buckets as array of arrays. CompilableFile[][] result = new CompilableFile[totaldepth][]; for (int i = 0; i < totaldepth; i++) { result[i] = (CompilableFile[])codeLevel[i].ToArray(typeof(CompilableFile)); } return(result); }
internal void foo(string virtualDir, HttpContext context) { _context = context; Hashtable compilableFiles = new Hashtable(SymbolHashCodeProvider.Default, SymbolEqualComparer.Default); string directory = _context.Request.MapPath(virtualDir) + "\\"; UnsafeNativeMethods.WIN32_FIND_DATA wfd; IntPtr hFindFile = UnsafeNativeMethods.FindFirstFile(directory + "*.*", out wfd); // No files: do nothing if (hFindFile == new IntPtr(-1)) { return; } try { // Go through all the files in the codegen dir. We use the Win32 native API's // directly for perf and memory usage reason (ASURT 97791) for (bool more = true; more; more = UnsafeNativeMethods.FindNextFile(hFindFile, out wfd)) { // Skip directories if ((wfd.dwFileAttributes & UnsafeNativeMethods.FILE_ATTRIBUTE_DIRECTORY) != 0) { continue; } string filename = directory + wfd.cFileName; CompilableFile cf = GetCompilableFileFromExtension(filename); // Ignore unknown extensions if (cf == null) { continue; } compilableFiles[filename] = cf; } } finally { UnsafeNativeMethods.FindClose(hFindFile); } foreach (CompilableFile cf in compilableFiles.Values) { ICollection references = cf.FileNameReferences; foreach (string reference in references) { CompilableFile dependentCf = (CompilableFile)compilableFiles[reference]; if (dependentCf != null) { cf.AddDependentCompilableFile(dependentCf); } } } CompilableFile[][] buckets = Split(compilableFiles); #if DBG for (int i = 0; i < buckets.Length; i++) { CompilableFile[] bucket = buckets[i]; Debug.Trace("Batching", ""); Debug.Trace("Batching", "Bucket " + i + " contains " + bucket.Length + " files"); for (int j = 0; j < bucket.Length; j++) { Debug.Trace("Batching", bucket[j].FileName); } } #endif }
internal void AddDependentCompilableFile(CompilableFile dependentCf) { _dependentCompilableFiles[dependentCf] = null; }