From 1ad596ca67f9952cce12c27c7d45fa5a97ab42ac Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 7 Dec 2017 11:06:40 -0500 Subject: [PATCH] Parallelizes directory copying and deletion --- TGS.Server/Helpers.cs | 61 ++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/TGS.Server/Helpers.cs b/TGS.Server/Helpers.cs index cb17f1fdce..9b3a163054 100644 --- a/TGS.Server/Helpers.cs +++ b/TGS.Server/Helpers.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Threading.Tasks; namespace TGS.Server { @@ -34,6 +36,8 @@ namespace TGS.Server /// If any files or directories in the root level of match anything in this of s, they won't be deleted. Incompatible with public static void DeleteDirectory(string path, bool ContentsOnly = false, IList excludeRoot = null) { + if (!ContentsOnly && excludeRoot != null && excludeRoot.Count > 0) + throw new ArgumentException("Cannot fully delete folder with exclusions specified!"); var di = new DirectoryInfo(path); if (!di.Exists) return; @@ -42,13 +46,7 @@ namespace TGS.Server excludeRoot[I] = excludeRoot[I].ToLower(); if (CheckDeleteSymlinkDir(di)) return; - NormalizeAndDelete(di, excludeRoot); - if (!ContentsOnly) - { - if (excludeRoot != null && excludeRoot.Count > 0) - throw new Exception("Cannot fully delete folder with exclusions specified!"); - di.Delete(true); - } + NormalizeAndDelete(di, excludeRoot, !ContentsOnly).Wait(); } @@ -72,24 +70,31 @@ namespace TGS.Server /// /// of the directory to empty /// Lowercase file and directory names to skip while emptying this level. Not passed forward - static void NormalizeAndDelete(DirectoryInfo dir, IList excludeRoot) + /// If , deletes on completion + /// A representing the operation + static async Task NormalizeAndDelete(DirectoryInfo dir, IList excludeRoot, bool deleteRoot) { + var tasks = new List(); foreach (var subDir in dir.GetDirectories()) { - if (excludeRoot != null && excludeRoot.Contains(subDir.Name.ToLower())) + var upperName = subDir.Name.ToUpperInvariant(); + if (excludeRoot != null && excludeRoot.Any(x => x.ToUpperInvariant() == upperName)) continue; if (CheckDeleteSymlinkDir(subDir)) continue; - NormalizeAndDelete(subDir, null); - subDir.Delete(true); + tasks.Add(NormalizeAndDelete(subDir, null, true)); } foreach (var file in dir.GetFiles()) { - if (excludeRoot != null && excludeRoot.Contains(file.Name.ToLower())) + var upperName = file.Name.ToUpperInvariant(); + if (excludeRoot != null && excludeRoot.Any(x => x.ToUpperInvariant() == upperName)) continue; file.Attributes = FileAttributes.Normal; file.Delete(); } + await Task.WhenAll(tasks); + if(deleteRoot) + dir.Delete(true); } /// @@ -110,7 +115,7 @@ namespace TGS.Server } else realIgnore = null; - CopyDirectoryImpl(sourceDirName, destDirName, realIgnore, ignoreIfNotExists); + CopyDirectoryImpl(sourceDirName, destDirName, realIgnore, ignoreIfNotExists).Wait(); } /// @@ -120,12 +125,10 @@ namespace TGS.Server /// The destination directory /// List of lowercase files and directories to ignore while copying /// If no error will be thrown if does not exist - static void CopyDirectoryImpl(string sourceDirName, string destDirName, IList ignore, bool ignoreIfNotExists) { + /// A representing the operation + static async Task CopyDirectoryImpl(string sourceDirName, string destDirName, IList ignore, bool ignoreIfNotExists) { // If the destination directory doesn't exist, create it. - if (!Directory.Exists(destDirName)) - { - Directory.CreateDirectory(destDirName); - } + Directory.CreateDirectory(destDirName); // Get the subdirectories for the specified directory. DirectoryInfo dir = new DirectoryInfo(sourceDirName); @@ -138,26 +141,30 @@ namespace TGS.Server + sourceDirName); } + var tasks = new List(); DirectoryInfo[] dirs = dir.GetDirectories(); + // copy them and their contents to new location. + foreach (DirectoryInfo subdir in dirs) + { + var upperName = subdir.Name.ToUpperInvariant(); + if (ignore != null && ignore.Any(x => x.ToUpperInvariant() == upperName)) + continue; + string temppath = Path.Combine(destDirName, subdir.Name); + tasks.Add(CopyDirectoryImpl(subdir.FullName, temppath, ignore, false)); + } // Get the files in the directory and copy them to the new location. FileInfo[] files = dir.GetFiles(); foreach (FileInfo file in files) { - if (ignore != null && ignore.Contains(file.Name.ToLower())) + var upperName = file.Name.ToUpperInvariant(); + if (ignore != null && ignore.Any(x => x.ToUpperInvariant() == upperName)) continue; string temppath = Path.Combine(destDirName, file.Name); file.CopyTo(temppath, true); } - // copy them and their contents to new location. - foreach (DirectoryInfo subdir in dirs) - { - if (ignore != null && ignore.Contains(subdir.Name.ToLower())) - continue; - string temppath = Path.Combine(destDirName, subdir.Name); - CopyDirectoryImpl(subdir.FullName, temppath, ignore, false); - } + await Task.WhenAll(tasks); } ///