From: Matthew M. <mma...@us...> - 2004-07-06 19:28:28
|
Update of /cvsroot/nant/nant/src/NAnt.Core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12847 Modified Files: DirectoryScanner.cs Log Message: Major win by eliminating regexes for non-wildcard patterns Regex comparisons take up the majority of the profiling run output Index: DirectoryScanner.cs =================================================================== RCS file: /cvsroot/nant/nant/src/NAnt.Core/DirectoryScanner.cs,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** DirectoryScanner.cs 30 Apr 2004 14:13:58 -0000 1.31 --- DirectoryScanner.cs 6 Jul 2004 19:28:19 -0000 1.32 *************** *** 112,115 **** --- 112,119 ---- private StringCollectionWithGoodToString _excludePatterns; + // holds the nant patterns converted to non-regex names (absolute canonized paths) + private StringCollectionWithGoodToString _includeNames; + private StringCollectionWithGoodToString _excludeNames; + // holds the result from a scan private StringCollectionWithGoodToString _fileNames; *************** *** 150,153 **** --- 154,161 ---- _excludePatterns.Clone(); } + if (_excludeNames != null) { + clone._excludeNames = (StringCollectionWithGoodToString) + _excludeNames.Clone(); + } clone._excludes = (StringCollectionWithGoodToString) _excludes.Clone(); if (_fileNames != null) { *************** *** 159,162 **** --- 167,174 ---- _includePatterns.Clone(); } + if (_includeNames != null) { + clone._includeNames = (StringCollectionWithGoodToString) + _includeNames.Clone(); + } clone._includes = (StringCollectionWithGoodToString) _includes.Clone(); if (_scannedDirectories != null) { *************** *** 257,261 **** --- 269,275 ---- public void Scan() { _includePatterns = new StringCollectionWithGoodToString (); + _includeNames = new StringCollectionWithGoodToString (); _excludePatterns = new StringCollectionWithGoodToString (); + _excludeNames = new StringCollectionWithGoodToString (); _fileNames = new StringCollectionWithGoodToString (); _directoryNames = new DirScannerStringCollection(); *************** *** 266,272 **** // convert given NAnt patterns to regex patterns with absolute paths // side effect: searchDirectories will be populated ! ConvertPatterns(_includes, _includePatterns, true); ! ConvertPatterns(_excludes, _excludePatterns, false); ! for (int index = 0; index < _searchDirectories.Count; index++) { ScanDirectory(_searchDirectories[index], (bool) _searchDirIsRecursive[index]); --- 280,286 ---- // convert given NAnt patterns to regex patterns with absolute paths // side effect: searchDirectories will be populated ! ConvertPatterns(_includes, _includePatterns, _includeNames, true); ! ConvertPatterns(_excludes, _excludePatterns, _excludeNames, false); ! for (int index = 0; index < _searchDirectories.Count; index++) { ScanDirectory(_searchDirectories[index], (bool) _searchDirIsRecursive[index]); *************** *** 284,301 **** /// <param name="nantPatterns">In. NAnt patterns. Absolute or relative paths.</param> /// <param name="regexPatterns">Out. Regex patterns. Absolute canonical paths.</param> /// <param name="addSearchDirectories">In. Whether to allow a pattern to add search directories.</param> /// <history> /// <change date="20020221" author="Ari Hännikäinen">Created</change> /// </history> ! private void ConvertPatterns(StringCollection nantPatterns, StringCollection regexPatterns, bool addSearchDirectories) { string searchDirectory; string regexPattern; bool isRecursive; foreach (string nantPattern in nantPatterns) { ! ParseSearchDirectoryAndPattern(nantPattern, out searchDirectory, out isRecursive, out regexPattern); ! if (!regexPatterns.Contains(regexPattern)) { ! regexPatterns.Add(regexPattern); ! } if (!addSearchDirectories) { continue; --- 298,324 ---- /// <param name="nantPatterns">In. NAnt patterns. Absolute or relative paths.</param> /// <param name="regexPatterns">Out. Regex patterns. Absolute canonical paths.</param> + /// <param name="nonRegexFiles">Out. Non-regex files. Absolute canonical paths.</param> /// <param name="addSearchDirectories">In. Whether to allow a pattern to add search directories.</param> /// <history> /// <change date="20020221" author="Ari Hännikäinen">Created</change> /// </history> ! private void ConvertPatterns(StringCollection nantPatterns, StringCollection regexPatterns, StringCollection nonRegexFiles, bool addSearchDirectories) { string searchDirectory; string regexPattern; bool isRecursive; + bool isRegex; foreach (string nantPattern in nantPatterns) { ! ParseSearchDirectoryAndPattern(nantPattern, out searchDirectory, out isRecursive, out isRegex, out regexPattern); ! if (isRegex) { ! if (!regexPatterns.Contains(regexPattern)) { ! regexPatterns.Add(regexPattern); ! } ! } else { ! if (!nonRegexFiles.Contains(regexPattern)) { ! nonRegexFiles.Add(regexPattern); ! } ! } ! if (!addSearchDirectories) { continue; *************** *** 326,329 **** --- 349,353 ---- /// <param name="searchDirectory">Out. Absolute canonical path to the directory to be searched</param> /// <param name="recursive">Out. Whether the pattern is potentially recursive or not</param> + /// <param name="isRegex">Out. Whether this is a regex pattern or not</param> /// <param name="regexPattern">Out. Regex search pattern (absolute canonical path)</param> /// <history> *************** *** 336,340 **** /// </change> /// </history> ! private void ParseSearchDirectoryAndPattern(string originalNAntPattern, out string searchDirectory, out bool recursive, out string regexPattern) { string s = originalNAntPattern; s = s.Replace('\\', Path.DirectorySeparatorChar); --- 360,364 ---- /// </change> /// </history> ! private void ParseSearchDirectoryAndPattern(string originalNAntPattern, out string searchDirectory, out bool recursive, out bool isRegex, out string regexPattern) { string s = originalNAntPattern; s = s.Replace('\\', Path.DirectorySeparatorChar); *************** *** 390,393 **** --- 414,424 ---- bool caseInsensitiveFS = !IsCaseSensitiveFileSystem(searchDirectory); + // if it's not a wildcard, just return + if (indexOfFirstWildcard == -1) { + regexPattern = CleanPath(searchDirectory, modifiedNAntPattern); + isRegex = false; + return; + } + //if the fs in case insensitive, make all the regex directories lowercase. regexPattern = ToRegexPattern( *************** *** 395,403 **** modifiedNAntPattern); - // specify pattern as case-insensitive if appropriate to this file system. if (caseInsensitiveFS) { regexPattern = "(?i)" + regexPattern; } } --- 426,435 ---- modifiedNAntPattern); // specify pattern as case-insensitive if appropriate to this file system. if (caseInsensitiveFS) { regexPattern = "(?i)" + regexPattern; } + + isRegex = true; } *************** *** 469,480 **** RegexOptions regexOptions = RegexOptions.None; if (!caseSensitive) { regexOptions |= RegexOptions.IgnoreCase; } ! // check path against includes ! foreach (string pattern in _includePatterns) { ! Match m = Regex.Match(path, pattern, regexOptions); ! if (m.Success) { included = true; break; --- 501,515 ---- RegexOptions regexOptions = RegexOptions.None; + CompareOptions compareOptions = CompareOptions.None; + CompareInfo compare = CultureInfo.InvariantCulture.CompareInfo; + if (!caseSensitive) { regexOptions |= RegexOptions.IgnoreCase; + compareOptions |= CompareOptions.IgnoreCase; } ! // check path against include names ! foreach (string name in _includeNames) { ! if (compare.Compare(name, path, compareOptions) == 0) { included = true; break; *************** *** 482,486 **** } ! // check path against excludes if (included) { foreach (string pattern in _excludePatterns) { --- 517,542 ---- } ! // check path against include regexes ! if (!included) { ! foreach (string pattern in _includePatterns) { ! Match m = Regex.Match(path, pattern, regexOptions); ! if (m.Success) { ! included = true; ! break; ! } ! } ! } ! ! // check path against exclude names ! if (included) { ! foreach (string name in _excludeNames) { ! if (compare.Compare(name, path, compareOptions) == 0) { ! included = false; ! break; ! } ! } ! } ! ! // check path against exclude regexes if (included) { foreach (string pattern in _excludePatterns) { *************** *** 500,503 **** --- 556,575 ---- #region Private Static Methods + private static string CleanPath(string baseDir, string nantPath) { + StringBuilder path = new StringBuilder(nantPath); + + // NAnt patterns can use either / \ as a directory seperator. + // We must replace both of these characters with Path.DirectorySeperatorChar + path.Replace('/', Path.DirectorySeparatorChar); + path.Replace('\\', Path.DirectorySeparatorChar); + + // Patterns MUST be full paths. + if (!Path.IsPathRooted(path.ToString())) { + path = new StringBuilder(Path.Combine(baseDir, path.ToString())); + } + + return path.ToString(); + } + /// <summary> /// Converts search pattern to a regular expression pattern. *************** *** 510,524 **** /// </history> private static string ToRegexPattern(string baseDir, string nantPattern) { ! StringBuilder pattern = new StringBuilder(nantPattern); ! ! // NAnt patterns can use either / \ as a directory seperator. ! // We must replace both of these characters with Path.DirectorySeperatorChar ! pattern.Replace('/', Path.DirectorySeparatorChar); ! pattern.Replace('\\', Path.DirectorySeparatorChar); ! ! // Patterns MUST be full paths. ! if (!Path.IsPathRooted(pattern.ToString())) { ! pattern = new StringBuilder(Path.Combine(baseDir, pattern.ToString())); ! } // The '\' character is a special character in regular expressions --- 582,586 ---- /// </history> private static string ToRegexPattern(string baseDir, string nantPattern) { ! StringBuilder pattern = new StringBuilder(CleanPath(baseDir, nantPattern)); // The '\' character is a special character in regular expressions |