public static DirectoryEntry ToFlatSearchResult(IFileSystemNameFactory fileSystemNameFactory, IEnumerable <FileSystemName> names) { Func <FileSystemName, FileSystemName> fileNameMapper = x => x; Func <FileSystemName, FileSystemEntryData> dataMapper = x => null; return(ToFlatSearchResult(fileSystemNameFactory, names, fileNameMapper, dataMapper)); }
public static DirectoryEntry ToFlatSearchResult <TSource>(IFileSystemNameFactory fileSystemNameFactory, IEnumerable <TSource> source, Func <TSource, FileSystemName> fileNameMapper, Func <TSource, FileSystemEntryData> dataMapper) { var sw = Stopwatch.StartNew(); // Group by root directory (typically one) var groups = source .GroupBy(x => GetProjectRoot(fileNameMapper(x))) .OrderBy(g => g.Key) .Select(group => new DirectoryEntry { Name = group.Key.FullPathName.FullName, Entries = CreateGroup(group, fileNameMapper, dataMapper).ToList() }); // Return entries by group var result = new DirectoryEntry() { Entries = groups.Cast <FileSystemEntry>().ToList() }; sw.Stop(); //Logger.Log("ToFlatSearchResult created {0} groups, first group contains {1:n0} elements in {2:n0} msec.", // result.Entries.Count, (result.Entries.Count >= 1 ? ((DirectoryEntry)result.Entries[0]).Entries.Count : -1), sw.ElapsedMilliseconds); return(result); }
public FileSystemSnapshotManager( IFileSystemNameFactory fileSystemNameFactory, IFileSystem fileSystem, IFileRegistrationTracker fileRegistrationTracker, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor operationProcessor, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory, ILongRunningFileSystemTaskQueue longRunningFileSystemTaskQueue) { _fileSystemNameFactory = fileSystemNameFactory; _fileSystem = fileSystem; _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _operationProcessor = operationProcessor; _projectDiscovery = projectDiscovery; _longRunningFileSystemTaskQueue = longRunningFileSystemTaskQueue; _fileRegistrationTracker = fileRegistrationTracker; _flushPathChangesTaskQueue = taskQueueFactory.CreateQueue("FileSystemSnapshotManager Path Changes Task Queue"); _fileRegistrationTracker.ProjectListChanged += FileRegistrationTrackerOnProjectListChanged; _fileRegistrationTracker.ProjectListRefreshed += FileRegistrationTrackerOnProjectListRefreshed; _fileSystemSnapshot = FileSystemSnapshot.Empty; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; _directoryChangeWatcher.Error += DirectoryChangeWatcherOnError; }
/// <summary> /// Return the |FileName| instance corresponding to the full path |path|. Returns |null| if |path| /// is invalid or not part of a project. /// </summary> public static Tuple <IProject, FileName> GetProjectFileName(IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, FullPathName path) { var project = projectDiscovery.GetProject(path); if (project == null) { return(null); } var rootPath = project.RootPath; var rootLength = rootPath.FullName.Length + 1; if (rootPath.FullName.Last() == Path.DirectorySeparatorChar) { rootLength--; } var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(rootPath); var relativePath = path.FullName.Substring(rootLength); var items = relativePath.Split(new char[] { Path.DirectorySeparatorChar }); foreach (var item in items) { if (item == items.Last()) { return(Tuple.Create(project, fileSystemNameFactory.CreateFileName(directoryName, item))); } directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, item); } return(null); }
public FileSystemChangesValidator( IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery) { _fileSystemNameFactory = fileSystemNameFactory; _projectDiscovery = projectDiscovery; }
/// <summary> /// Return the |FileName| instance corresponding to the full path |path|. /// Returns |null| if |path| is invalid or not part of a project. /// </summary> public static ProjectFileName GetProjectFileName(IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, FullPath path) { var project = projectDiscovery.GetProject(path); if (project == null) { return(default(ProjectFileName)); } var split = PathHelpers.SplitPrefix(path.Value, project.RootPath.Value); var relativePath = split.Suffix; var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(project.RootPath); var names = relativePath.Split(Path.DirectorySeparatorChar); foreach (var name in names) { if (name == names.Last()) { return(new ProjectFileName(project, fileSystemNameFactory.CreateFileName(directoryName, name))); } directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, name); } return(default(ProjectFileName)); }
/// <summary> /// Return the <see cref="ProjectFileName"/> instance of the project file <paramref name="relativePath"/>. /// Returns the default value if <paramref name="relativePath"/> is invalid or not part of a project. /// </summary> public static ProjectFileName CreateProjectFileNameFromRelativePath( this IFileSystemNameFactory fileSystemNameFactory, IProject project, string relativePath) { if (project == null) { throw new ArgumentNullException(); } if (string.IsNullOrEmpty(relativePath)) { return(default(ProjectFileName)); } var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(project.RootPath); var names = PathHelpers.SplitPath(relativePath).ToList(); foreach (var name in names) { if (name == names.Last()) { return(new ProjectFileName(project, fileSystemNameFactory.CreateFileName(directoryName, name))); } directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, name); } Debug.Assert(false, "Unreachable code"); throw new InvalidOperationException(); }
public FileSystemSnapshotManager( IFileSystemNameFactory fileSystemNameFactory, IFileSystem fileSystem, IFileRegistrationTracker fileRegistrationTracker, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor operationProcessor, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory, ILongRunningFileSystemTaskQueue longRunningFileSystemTaskQueue) { _fileSystemNameFactory = fileSystemNameFactory; _fileSystem = fileSystem; _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _operationProcessor = operationProcessor; _projectDiscovery = projectDiscovery; _longRunningFileSystemTaskQueue = longRunningFileSystemTaskQueue; _fileRegistrationTracker = fileRegistrationTracker; _flushPathChangesTaskQueue = taskQueueFactory.CreateQueue("FileSystemSnapshotManager Path Changes Task Queue"); _taskExecutor = taskQueueFactory.CreateQueue("FileSystemSnapshotManager State Change Task Queue"); _fileRegistrationTracker.ProjectListChanged += FileRegistrationTrackerOnProjectListChanged; _currentSnapshot = FileSystemSnapshot.Empty; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(TimeSpan.FromSeconds(60)); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; _directoryChangeWatcher.Error += DirectoryChangeWatcherOnError; _directoryChangeWatcher.Paused += DirectoryChangeWatcherOnPaused; _directoryChangeWatcher.Resumed += DirectoryChangeWatcherOnResumed; }
public FileSystemSnapshot Compute(IFileSystemNameFactory fileNameFactory, FileSystemSnapshot oldSnapshot, FullPathChanges pathChanges /* may be null */, IList <IProject> projects, int version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // cancellation using (var progress = _progressTrackerFactory.CreateIndeterminateTracker()) { var projectRoots = projects .Distinct(new ProjectPathComparer()) .Select(project => { cancellationToken.ThrowIfCancellationRequested(); // cancellation var projectSnapshotBuilder = new ProjectRootSnapshotBuilder( _fileSystem, fileNameFactory, oldSnapshot, project, progress, (pathChanges == null ? null : new ProjectPathChanges(project.RootPath, pathChanges.Entries)), cancellationToken); var rootSnapshot = projectSnapshotBuilder.Build(); return(new ProjectRootSnapshot(project, rootSnapshot)); }) .OrderBy(projectRoot => projectRoot.Directory.DirectoryName) .ToReadOnlyCollection(); return(new FileSystemSnapshot(version, projectRoots)); } }
public FileSystemTreeSnapshot Compute( IFileSystemNameFactory fileNameFactory, FileSystemTreeSnapshot oldSnapshot, FullPathChanges pathChanges /* may be null */, List <FullPath> rootFiles, int version) { using (var progress = _progressTrackerFactory.CreateIndeterminateTracker()) { var projectRoots = rootFiles .Select(filename => _projectDiscovery.GetProject(filename)) .Where(project => project != null) .Distinct(new ProjectPathComparer()) .Select(project => { var data = new ProjectProcessingData { FileSystemNameFactory = fileNameFactory, Project = project, Progress = progress, OldSnapshot = oldSnapshot, PathChanges = (pathChanges == null ? null : new ProjectPathChanges(project.RootPath, pathChanges.Entries)), }; var rootSnapshot = ProcessProject(data); return(new ProjectRootSnapshot(project, rootSnapshot)); }) .OrderBy(projectRoot => projectRoot.Directory.DirectoryName) .ToReadOnlyCollection(); return(new FileSystemTreeSnapshot(version, projectRoots)); } }
/// <summary> /// Enumerate directories and files under the project path of |projet|. /// </summary> private IEnumerable <TraversedDirectoryEntry> TraverseFileSystem(IFileSystemNameFactory fileNameFactory, IProject project, DirectoryName projectPath) { Debug.Assert(projectPath.IsAbsoluteName); var stack = new Stack <DirectoryName>(); stack.Push(projectPath); while (stack.Count > 0) { var head = stack.Pop(); if (head.IsAbsoluteName || project.DirectoryFilter.Include(head.RelativePathName.RelativeName)) { IList <string> childDirectories; IList <string> childFiles; RelativePathNameExtensions.GetFileSystemEntries(project.RootPath, head.RelativePathName, out childDirectories, out childFiles); // Note: Use "for" loop to avoid memory allocations. for (var i = 0; i < childDirectories.Count; i++) { stack.Push(fileNameFactory.CreateDirectoryName(head, childDirectories[i])); } // Note: Use "for" loop to avoid memory allocations. var childFilenames = new FileName[childFiles.Count]; for (var i = 0; i < childFiles.Count; i++) { childFilenames[i] = fileNameFactory.CreateFileName(head, childFiles[i]); } yield return(new TraversedDirectoryEntry(head, childFilenames)); } } }
private void RecomputeGraph() { _snapshotOperationProcessor.Execute(new OperationInfo <SnapshotComputedEventArgs> { OnBeforeExecute = args => OnSnapshotComputing(args), OnAfterExecute = args => OnSnapshotComputed(args), Execute = args => { Logger.Log("Collecting list of files from file system."); Logger.LogMemoryStats(); var sw = Stopwatch.StartNew(); var files = new List <FullPathName>(); lock (_lock) { ValidateKnownFiles(); files.AddRange(_addedFiles); } IFileSystemNameFactory fileNameFactory = _fileSystemNameFactory; if (ReuseFileNameInstances) { if (_fileSystemSnapshot.ProjectRoots.Count > 0) { fileNameFactory = new FileSystemTreeSnapshotNameFactory(_fileSystemSnapshot, fileNameFactory); } } var newSnapshot = _fileSystemSnapshotBuilder.Compute(fileNameFactory, files, Interlocked.Increment(ref _version)); // Monitor all the Chromium directories for changes. var newRoots = newSnapshot.ProjectRoots .Select(entry => entry.Directory.DirectoryName); _directoryChangeWatcher.WatchDirectories(newRoots); // Update current tree atomically FileSystemTreeSnapshot previousSnapshot; lock (_lock) { previousSnapshot = _fileSystemSnapshot; _fileSystemSnapshot = newSnapshot; } sw.Stop(); Logger.Log(">>>>>>>> Done collecting list of files: {0:n0} files in {1:n0} directories collected in {2:n0} msec.", newSnapshot.ProjectRoots.Aggregate(0, (acc, x) => acc + CountFileEntries(x.Directory)), newSnapshot.ProjectRoots.Aggregate(0, (acc, x) => acc + CountDirectoryEntries(x.Directory)), sw.ElapsedMilliseconds); Logger.LogMemoryStats(); return(new SnapshotComputedEventArgs { PreviousSnapshot = previousSnapshot, NewSnapshot = newSnapshot }); } }); }
/// <summary> /// Return the <see cref="ProjectFileName"/> instance of the full path <paramref name="path"/>. /// Returns the default value if <paramref name="path"/> is invalid or not part of a project. /// </summary> public static ProjectFileName CreateProjectFileFromFullPath(this IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, FullPath path) { var project = projectDiscovery.GetProject(path); if (project == null) { return(default(ProjectFileName)); } var split = PathHelpers.SplitPrefix(path.Value, project.RootPath.Value); return(CreateProjectFileNameFromRelativePath(fileSystemNameFactory, project, new RelativePath(split.Suffix))); }
public FileSystemTreeSnapshot Compute(IFileSystemNameFactory fileNameFactory, IEnumerable <FullPathName> filenames, int version) { using (var progress = _progressTrackerFactory.CreateIndeterminateTracker()) { var projectRoots = filenames .Select(filename => _projectDiscovery.GetProject(filename)) .Where(project => project != null) .Distinct(new ProjectPathComparer()) .Select(project => new ProjectRootSnapshot(project, ProcessProject(fileNameFactory, project, progress))) .OrderBy(projectRoot => projectRoot.Directory.DirectoryName) .ToReadOnlyCollection(); return(new FileSystemTreeSnapshot(version, projectRoots)); } }
public ProjectRootSnapshotBuilder(IFileSystem fileSystem, IFileSystemNameFactory fileSystemNameFactory, FileSystemSnapshot oldSnapshot, IProject project, IProgressTracker progress, ProjectPathChanges pathChanges, CancellationToken cancellationToken) { _fileSystem = fileSystem; _fileSystemNameFactory = fileSystemNameFactory; _oldSnapshot = oldSnapshot; _project = project; _progress = progress; _pathChanges = pathChanges; _cancellationToken = cancellationToken; }
public FileSystemProcessor( IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor <SnapshotComputedEventArgs> snapshotOperationProcessor) { _fileSystemNameFactory = fileSystemNameFactory; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(); _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _snapshotOperationProcessor = snapshotOperationProcessor; _projectDiscovery = projectDiscovery; _taskQueue = taskQueueFactory.CreateQueue(); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; _fileSystemSnapshot = FileSystemTreeSnapshot.Empty; }
public FileSystemProcessor( IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor<SnapshotComputedEventArgs> snapshotOperationProcessor) { _fileSystemNameFactory = fileSystemNameFactory; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(); _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _snapshotOperationProcessor = snapshotOperationProcessor; _projectDiscovery = projectDiscovery; _taskQueue = taskQueueFactory.CreateQueue(); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; _fileSystemSnapshot = FileSystemTreeSnapshot.Empty; }
public FileSystemProcessor( IFileSystemNameFactory fileSystemNameFactory, IFileSystem fileSystem, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor operationProcessor, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory) { _fileSystemNameFactory = fileSystemNameFactory; _fileSystem = fileSystem; _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _operationProcessor = operationProcessor; _projectDiscovery = projectDiscovery; _taskQueue = taskQueueFactory.CreateQueue("FileSystemProcessor Task Queue"); _fileSystemSnapshot = FileSystemTreeSnapshot.Empty; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; }
public FileSystemProcessor( IFileSystemNameFactory fileSystemNameFactory, IFileSystem fileSystem, IFileSystemSnapshotBuilder fileSystemSnapshotBuilder, IOperationProcessor operationProcessor, IProjectDiscovery projectDiscovery, IDirectoryChangeWatcherFactory directoryChangeWatcherFactory, ITaskQueueFactory taskQueueFactory) { _fileSystemNameFactory = fileSystemNameFactory; _fileSystem = fileSystem; _fileSystemSnapshotBuilder = fileSystemSnapshotBuilder; _operationProcessor = operationProcessor; _projectDiscovery = projectDiscovery; _taskQueue = taskQueueFactory.CreateQueue("FileSystemProcessor Task Queue"); _fileSystemSnapshot = FileSystemTreeSnapshot.Empty; _directoryChangeWatcher = directoryChangeWatcherFactory.CreateWatcher(); _directoryChangeWatcher.PathsChanged += DirectoryChangeWatcherOnPathsChanged; _directoryChangeWatcher.Error += DirectoryChangeWatcherOnError; }
public SearchEngine( IFileSystemSnapshotManager fileSystemSnapshotManager, IFileSystemNameFactory fileSystemNameFactory, ILongRunningFileSystemTaskQueue taskQueue, IFileDatabaseSnapshotFactory fileDatabaseSnapshotFactory, IProjectDiscovery projectDiscovery, ICompiledTextSearchDataFactory compiledTextSearchDataFactory, IOperationProcessor operationProcessor) { _fileSystemNameFactory = fileSystemNameFactory; _taskQueue = taskQueue; _fileDatabaseSnapshotFactory = fileDatabaseSnapshotFactory; _projectDiscovery = projectDiscovery; _compiledTextSearchDataFactory = compiledTextSearchDataFactory; _operationProcessor = operationProcessor; // Create a "Null" state _currentFileDatabase = _fileDatabaseSnapshotFactory.CreateEmpty(); // Setup computing a new state everytime a new tree is computed. fileSystemSnapshotManager.SnapshotScanFinished += FileSystemSnapshotManagerOnSnapshotScanFinished; fileSystemSnapshotManager.FilesChanged += FileSystemSnapshotManagerOnFilesChanged; }
public SearchEngine( IFileSystemProcessor fileSystemProcessor, IFileSystemNameFactory fileSystemNameFactory, ITaskQueueFactory taskQueueFactory, IFileDatabaseFactory fileDatabaseFactory, IProjectDiscovery projectDiscovery, ICompiledTextSearchDataFactory compiledTextSearchDataFactory, IOperationProcessor operationProcessor) { _fileSystemNameFactory = fileSystemNameFactory; _taskQueue = taskQueueFactory.CreateQueue("SearchEngine Task Queue"); _fileDatabaseFactory = fileDatabaseFactory; _projectDiscovery = projectDiscovery; _compiledTextSearchDataFactory = compiledTextSearchDataFactory; _operationProcessor = operationProcessor; // Create a "Null" state _currentFileDatabase = _fileDatabaseFactory.CreateEmpty(); // Setup computing a new state everytime a new tree is computed. fileSystemProcessor.SnapshotComputed += FileSystemProcessorOnSnapshotComputed; fileSystemProcessor.FilesChanged += FileSystemProcessorOnFilesChanged; }
public SearchEngine( IFileSystemProcessor fileSystemProcessor, IFileSystemNameFactory fileSystemNameFactory, ICustomThreadPool customThreadPool, IFileDatabaseFactory fileDatabaseFactory, IProjectDiscovery projectDiscovery, ISearchStringParser searchStringParser, IOperationProcessor <OperationResultEventArgs> fileLoadingOperationProcessor) { _fileSystemNameFactory = fileSystemNameFactory; _customThreadPool = customThreadPool; _fileDatabaseFactory = fileDatabaseFactory; _projectDiscovery = projectDiscovery; _searchStringParser = searchStringParser; _fileLoadingOperationProcessor = fileLoadingOperationProcessor; // Create a "Null" state _currentFileDatabase = _fileDatabaseFactory.CreateEmpty(); // Setup computing a new state everytime a new tree is computed. fileSystemProcessor.SnapshotComputed += FileSystemProcessorOnSnapshotComputed; fileSystemProcessor.FilesChanged += FileSystemProcessorOnFilesChanged; }
public FileSystemSnapshot Compute(IFileSystemNameFactory fileNameFactory, FileSystemSnapshot oldSnapshot, FullPathChanges pathChanges /* may be null */, IList <IProject> projects, int version, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // cancellation using (var progress = _progressTrackerFactory.CreateIndeterminateTracker()) { // Clear file name factory intern tables if no projects. We could be // more aggressive at the expense of decreasing string interning. if (projects.Count == 0) { fileNameFactory.ClearInternedStrings(); } var projectRoots = projects .Distinct(new ProjectPathComparer()) .Select(project => { cancellationToken.ThrowIfCancellationRequested(); // cancellation var projectSnapshotBuilder = new ProjectRootSnapshotBuilder( _fileSystem, fileNameFactory, oldSnapshot, project, progress, (pathChanges == null ? null : new ProjectPathChanges(project.RootPath, pathChanges.Entries)), cancellationToken); var rootSnapshot = projectSnapshotBuilder.Build(); return(new ProjectRootSnapshot(project, rootSnapshot)); }) .OrderBy(projectRoot => projectRoot.Directory.DirectoryName) .ToReadOnlyCollection(); return(new FileSystemSnapshot(version, projectRoots)); } }
public SearchDirectoryNamesRequestHandler(ISearchEngine searchEngine, IFileSystemNameFactory fileSystemNameFactory) { _searchEngine = searchEngine; _fileSystemNameFactory = fileSystemNameFactory; }
public SearchFileContentsRequestHandler(ISearchEngine searchEngine, IFileSystemNameFactory fileSystemNameFactory) { _searchEngine = searchEngine; _fileSystemNameFactory = fileSystemNameFactory; }
/// <summary> /// Return the <see cref="ProjectFileName"/> instance of the project file <paramref name="relativePath"/>. /// Returns the default value if <paramref name="relativePath"/> is invalid or not part of a project. /// </summary> public static ProjectFileName CreateProjectFileNameFromRelativePath( this IFileSystemNameFactory fileSystemNameFactory, IProject project, RelativePath relativePath) { return(CreateProjectFileNameFromRelativePath(fileSystemNameFactory, project, relativePath.Value)); }
public FileSystemTreeSnapshotNameFactory(FileSystemTreeSnapshot snapshot, IFileSystemNameFactory previous) { _snapshot = snapshot; _previous = previous; }
private DirectorySnapshot ProcessProject(IFileSystemNameFactory fileNameFactory, IProject project, IProgressTracker progress) { var projectPath = fileNameFactory.CreateAbsoluteDirectoryName(project.RootPath); var ssw = new ScopedStopWatch(); // Create list of pairs (DirectoryName, List[FileNames]) var directoriesWithFiles = TraverseFileSystem(fileNameFactory, project, projectPath) .AsParallel() .WithExecutionMode(ParallelExecutionMode.ForceParallelism) .Select(traversedDirectoryEntry => { var directoryName = traversedDirectoryEntry.DirectoryName; if (progress.Step()) { progress.DisplayProgress((i, n) => string.Format("Traversing directory: {0}\\{1}", project.RootPath.FullName, directoryName.RelativePathName.RelativeName)); } var entries = traversedDirectoryEntry.ChildrenNames .Where(childFilename => project.FileFilter.Include(childFilename.RelativePathName.RelativeName)) .OrderBy(x => x.RelativePathName) .ToReadOnlyCollection(); return(KeyValuePair.Create(directoryName, entries)); }) .ToList(); ssw.Step(sw => Logger.Log("Done traversing file system in {0:n0} msec.", sw.ElapsedMilliseconds)); // 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.RelativePathName.CompareTo(y.Key.RelativePathName)); ssw.Step(sw => Logger.Log("Done sorting list of directories in {0:n0} msec.", sw.ElapsedMilliseconds)); // 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.IsAbsoluteName) { return; } GetOrCreateList(directoriesToChildDirectories, directoryName.Parent).Add(directoryName); }); ssw.Step(sw => Logger.Log("Done creating children directories in {0:n0} msec.", sw.ElapsedMilliseconds)); // 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 directoryName = entry.Key; var childFilenames = entry.Value; var childDirectories = GetOrEmptyList(directoriesToChildDirectories, directoryName) .Select(x => directoriesToSnapshot[x]) .OrderBy(x => x.DirectoryName.RelativePathName) .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(directoryName, childDirectories, childFilenames); directoriesToSnapshot.Add(directoryName, result); return(result); }) .ToList(); ssw.Step(sw => Logger.Log("Done creating directory snapshots in {0:n0} msec.", sw.ElapsedMilliseconds)); // 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(projectPath)); return(directorySnapshots.Last()); }
public SearchFileNamesRequestHandler(ISearchEngine searchEngine, IFileSystemNameFactory fileSystemNameFactory) { _searchEngine = searchEngine; _fileSystemNameFactory = fileSystemNameFactory; }