private static void ProcessDirectory(IProject project, DirectorySnapshot directory, List<KeyValuePair<IProject, DirectorySnapshot>> result)
 {
     result.Add(KeyValuePair.Create(project, directory));
       foreach (var child in directory.DirectoryEntries) {
     ProcessDirectory(project, child, result);
       }
 }
 private static List<FileSystemEntry> BuildEntries(DirectorySnapshot directoryEntry)
 {
     return directoryEntry.DirectoryEntries
     .Select(x => BuildDirectoryEntry(x))
     .Concat(directoryEntry.Files.Select(x => BuildFileEntry(x)))
     .ToList();
 }
 private static DirectoryEntry BuildDirectoryEntry(DirectorySnapshot directoryEntry) {
   return new DirectoryEntry {
     Name = (directoryEntry.DirectoryName.IsAbsoluteName ? directoryEntry.DirectoryName.FullPath.Value : directoryEntry.DirectoryName.RelativePath.FileName),
     Data = null,
     Entries = BuildEntries(directoryEntry)
   };
 }
 private static List <FileSystemEntry> BuildEntries(DirectorySnapshot directoryEntry)
 {
     return(directoryEntry.ChildDirectories
            .Select(x => BuildDirectoryEntry(x))
            .Concat(directoryEntry.ChildFiles.Select(x => BuildFileEntry(x)))
            .ToList());
 }
Example #5
0
 private static void ProcessDirectory(IProject project, DirectorySnapshot directory, List <KeyValuePair <IProject, DirectorySnapshot> > result)
 {
     result.Add(KeyValuePair.Create(project, directory));
     foreach (var child in directory.DirectoryEntries)
     {
         ProcessDirectory(project, child, result);
     }
 }
 private static DirectoryEntry BuildDirectoryEntry(DirectorySnapshot directoryEntry)
 {
     return(new DirectoryEntry {
         Name = (directoryEntry.DirectoryName.IsAbsoluteName ? directoryEntry.DirectoryName.FullPath.Value : directoryEntry.DirectoryName.RelativePath.FileName),
         Data = null,
         Entries = BuildEntries(directoryEntry)
     });
 }
 private static void VisitDirectory(
   IProject project,
   DirectorySnapshot directory,
   Action<IProject, DirectorySnapshot> callback) {
   callback(project, directory);
   foreach (var child in directory.ChildDirectories) {
     VisitDirectory(project, child, callback);
   }
 }
Example #8
0
 private static void VisitDirectory(
     IProject project,
     DirectorySnapshot directory,
     Action <IProject, DirectorySnapshot> callback)
 {
     callback(project, directory);
     foreach (var child in directory.ChildDirectories)
     {
         VisitDirectory(project, child, callback);
     }
 }
 public ProjectRootSnapshot(IProject project, DirectorySnapshot directory)
 {
     _project   = project;
     _directory = directory;
 }
 private int CountFileEntries(DirectorySnapshot entry)
 {
     return
     entry.Files.Count +
     entry.DirectoryEntries.Aggregate(0, (acc, x) => acc + CountFileEntries(x));
 }
Example #11
0
        private DirectorySnapshot CreateDirectorySnapshot(
            ProjectProcessingData data,
            DirectoryName directory,
            bool isSymLink)
        {
            // Create list of pairs (DirectoryName, List[FileNames])
            var directoriesWithFiles = TraverseFileSystem(data, directory, isSymLink)
                                       .AsParallel()
                                       .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                                       .Select(traversedDirectoryEntry => {
                var directoryName = traversedDirectoryEntry.DirectoryData.DirectoryName;
                if (data.Progress.Step())
                {
                    data.Progress.DisplayProgress((i, n) => string.Format("Traversing directory: {0}\\{1}", data.Project.RootPath.Value, directoryName.RelativePath.Value));
                }
                var fileNames = traversedDirectoryEntry.ChildFileNames
                                .Where(childFilename => data.Project.FileFilter.Include(childFilename.RelativePath))
                                .OrderBy(x => x.RelativePath)
                                .ToReadOnlyCollection();

                return(KeyValuePair.Create(traversedDirectoryEntry.DirectoryData, fileNames));
            })
                                       .ToList();

            // We sort entries by directory name *descending* to make sure we process
            // directories bottom up, so that we know
            // 1) it is safe to skip DirectoryEntry instances where "Entries.Count" == 0,
            // 2) we create instances of child directories before their parent.
            directoriesWithFiles.Sort((x, y) => - x.Key.DirectoryName.RelativePath.CompareTo(y.Key.DirectoryName.RelativePath));

            // Build map from parent directory -> list of child directories
            var directoriesToChildDirectories = new Dictionary <DirectoryName, List <DirectoryName> >();

            directoriesWithFiles.ForAll(x => {
                var directoryName = x.Key;

                // Ignore root project directory name
                if (directoryName.DirectoryName.IsAbsoluteName)
                {
                    return;
                }

                GetOrCreateList(directoriesToChildDirectories, directoryName.DirectoryName.Parent).Add(directoryName.DirectoryName);
            });

            // Build directory snapshots for each directory entry, using an
            // intermediate map to enable connecting snapshots to their parent.
            var directoriesToSnapshot = new Dictionary <DirectoryName, DirectorySnapshot>();
            var directorySnapshots    = directoriesWithFiles.Select(entry => {
                var directoryElement = entry.Key;
                var childFilenames   = entry.Value;

                var childDirectories = GetOrEmptyList(directoriesToChildDirectories, directoryElement.DirectoryName)
                                       .Select(x => directoriesToSnapshot[x])
                                       .OrderBy(x => x.DirectoryName.RelativePath)
                                       .ToReadOnlyCollection();

                // TODO(rpaquay): Not clear the lines below are a perf win, even though
                // they do not hurt correctness.
                // Remove children since we processed them
                //GetOrEmptyList(directoriesToChildDirectories, directoryName)
                //  .ForAll(x => directoriesToSnapshot.Remove(x));

                var result = new DirectorySnapshot(directoryElement, childDirectories, childFilenames);
                directoriesToSnapshot.Add(directoryElement.DirectoryName, result);
                return(result);
            })
                                        .ToList();

            // Since we sort directories by name descending, the last entry is always the
            // entry correcsponding to the project root.
            Debug.Assert(directorySnapshots.Count >= 1);
            Debug.Assert(directorySnapshots.Last().DirectoryName.Equals(directory));
            return(directorySnapshots.Last());
        }
Example #12
0
        private DirectorySnapshot ApplyDirectorySnapshotDelta(
            ProjectProcessingData data,
            DirectorySnapshot oldDirectory)
        {
            var oldDirectoryPath = oldDirectory.DirectoryName.RelativePath;

            // Create lists of created dirs and files. We havet to access the file system to know
            // if each path is a file or a directory.
            List <IFileInfoSnapshot> createDirs   = null;
            List <IFileInfoSnapshot> createdFiles = null;

            foreach (var path in data.PathChanges.GetCreatedEntries(oldDirectoryPath).ToForeachEnum())
            {
                var info = _fileSystem.GetFileInfoSnapshot(data.Project.RootPath.Combine(path));
                if (info.IsDirectory)
                {
                    if (createDirs == null)
                    {
                        createDirs = new List <IFileInfoSnapshot>();
                    }
                    createDirs.Add(info);
                }
                else if (info.IsFile)
                {
                    if (createdFiles == null)
                    {
                        createdFiles = new List <IFileInfoSnapshot>();
                    }
                    createdFiles.Add(info);
                }
            }

            // Recursively create new directory entires for previous (non deleted)
            // entries.
            var childDirectories = oldDirectory.ChildDirectories
                                   .Where(dir => !data.PathChanges.IsDeleted(dir.DirectoryName.RelativePath))
                                   .Select(dir => ApplyDirectorySnapshotDelta(data, dir))
                                   .ToList();

            // Add created directories
            if (createDirs != null)
            {
                foreach (var info in createDirs.ToForeachEnum())
                {
                    var name          = data.FileSystemNameFactory.CreateDirectoryName(oldDirectory.DirectoryName, info.Path.FileName);
                    var childSnapshot = CreateDirectorySnapshot(data, name, info.IsSymLink);

                    // Note: File system change notifications are not always 100%
                    // reliable. We may get a "create" event for directory we already know
                    // about.
                    var index = childDirectories.FindIndex(x =>
                                                           SystemPathComparer.Instance.StringComparer.Equals(x.DirectoryName.RelativePath.FileName, name.RelativePath.FileName));
                    if (index >= 0)
                    {
                        childDirectories.RemoveAt(index);
                    }
                    childDirectories.Add(childSnapshot);
                }

                // We need to re-sort the array since we added new entries
                childDirectories.Sort((x, y) =>
                                      SystemPathComparer.Instance.StringComparer.Compare(x.DirectoryName.RelativePath.FileName, y.DirectoryName.RelativePath.FileName));
            }

            // Match non deleted files
            // Sepcial case: if no file deleted or created, just re-use the list.
            IList <FileName> newFileList;

            if (data.PathChanges.GetDeletedEntries(oldDirectoryPath).Count == 0 && createdFiles == null)
            {
                newFileList = oldDirectory.ChildFiles;
            }
            else
            {
                // Copy the list of previous children, minus deleted files.
                var newFileListTemp = oldDirectory.ChildFiles
                                      .Where(x => !data.PathChanges.IsDeleted(x.RelativePath))
                                      .ToList();

                // Add created files
                if (createdFiles != null)
                {
                    foreach (var info in createdFiles.ToForeachEnum())
                    {
                        var name = data.FileSystemNameFactory.CreateFileName(oldDirectory.DirectoryName, info.Path.FileName);
                        newFileListTemp.Add(name);
                    }

                    // We need to re-sort the array since we added new entries
                    newFileListTemp.Sort((x, y) =>
                                         SystemPathComparer.Instance.StringComparer.Compare(x.RelativePath.FileName, y.RelativePath.FileName));

                    // Note: File system change notifications are not always 100%
                    // reliable. We may get a "create" event for files we already know
                    // about.
                    ArrayUtilities.RemoveDuplicates(newFileListTemp, (x, y) =>
                                                    SystemPathComparer.Instance.StringComparer.Equals(x.RelativePath.FileName, y.RelativePath.FileName));
                }
                newFileList = newFileListTemp;
            }

            var newData = new DirectoryData(oldDirectory.DirectoryName, oldDirectory.IsSymLink);

            return(new DirectorySnapshot(
                       newData,
                       childDirectories.ToReadOnlyCollection(),
                       newFileList.ToReadOnlyCollection()));
        }
Example #13
0
 public ProjectRootSnapshot(IProject project, DirectorySnapshot directory) {
   _project = project;
   _directory = directory;
 }
Example #14
0
 private int CountDirectoryEntries(DirectorySnapshot entry) {
   return
     1 +
     entry.ChildDirectories.Aggregate(0, (acc, x) => acc + CountDirectoryEntries(x));
 }