private void Grow() { Invariants.Assert(_count == _entries.Length); Invariants.Assert(_count == _buckets.Length); Invariants.Assert(_freeListHead == -1); var oldEntries = _entries; var oldLength = _entries.Length; var newLength = HashCode.GetPrime(GrowSize(oldLength)); var newBuckets = new int[newLength]; var newEntries = new Entry[newLength]; Array.Copy(_entries, newEntries, _entries.Length); for (var entryIndex = 0; entryIndex < oldEntries.Length; entryIndex++) { var oldEntry = oldEntries[entryIndex]; if (oldEntry.IsValid) { var newBucketIndex = GetBucketIndex(oldEntry.HashCode, newLength); newEntries[entryIndex].SetNextIndex(AdjustBucketIndexRead(newBuckets[newBucketIndex])); newBuckets[newBucketIndex] = AdjustBucketIndexWrite(entryIndex); } } _buckets = newBuckets; _entries = newEntries; }
public void TestDefaults() { var q = new SampleStream(Invariants.Targeted(new[] { new QuantileEpsilonPair(0.99d, 0.001d) })); double g = q.Query(0.99); Assert.Equal(double.NaN, g); }
/// <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); } throw Invariants.Fail("Unreachable code"); }
internal LayerContext(Invariants invariants, Layer previousLayer, Layer currentLayer, int currentLayerIndex) { m_invariants = invariants; PreviousLayer = previousLayer; CurrentLayer = currentLayer; CurrentLayerIndex = currentLayerIndex; }
private NodeViewModel CreateNodeViewModel(FileSystemEntry entry, NodeViewModel parent) { Invariants.Assert(entry != null); Invariants.Assert(parent != null); var directoryEntry = entry as DirectoryEntry; var node = directoryEntry != null ? (NodeViewModel) new DirectoryNodeViewModel() : (NodeViewModel) new FileNodeViewModel(); node.Caption = entry.Name; node.Name = entry.Name; if (PathHelpers.IsAbsolutePath(node.Name)) { node.Template = _templateFactory.ProjectTemplate; } else if (directoryEntry != null) { node.Template = _templateFactory.DirectoryTemplate; } else { var extension = Path.GetExtension(entry.Name); Invariants.Assert(extension != null); node.Template = _templateFactory.GetFileTemplate(extension); if (node.Template.Icon == null) { if (!_fileTemplatesToInitialize.ContainsKey(extension)) { _fileTemplatesToInitialize.Add(extension, node.Template); } } } return(node); }
public static ArrayDiffsResult <T> BuildArrayDiffs <T>( IList <T> leftList, IList <T> rightList, IEqualityComparer <T> comparer) { comparer = comparer ?? EqualityComparer <T> .Default; var result = ProcessSpecialCases(leftList, rightList, comparer); if (result != null) { return(result.Value); } bool smallList = leftList.Count + rightList.Count <= SmallArrayThreshold; var result2 = smallList ? BuildArrayDiffsForSmallArrays(leftList, rightList, comparer) : BuildArrayDiffsForLargeArrays(leftList, rightList, comparer); // Quick check assumption about identity is verified: both list should not // contain duplicate elements. Invariants.Assert( result2.LeftOnlyItems.Count + result2.RightOnlyItems.Count + result2.CommonItems.Count * 2 == leftList.Count + rightList.Count); return(result2); }
private bool IsFileContentsUpToDate(FileSystemEntities entities, FullPathChanges fullPathChanges, FileWithContents existingFileWithContents) { Invariants.Assert(existingFileWithContents.Contents != null); var fullPath = existingFileWithContents.FileName.FullPath; if (fullPathChanges != null) { // We don't get file change events for file in symlinks, so we can't // rely on fullPathChanges contents for our heuristic of avoiding file // system access. // Actually, since we cannot reliable detect changes in symlinks, we enable this // optimization anyways, as we rely on the user to manually refresh the index // (that results in a "null" value for fullPathChanges) //if (!FileDatabaseSnapshot.IsContainedInSymLinkHelper(entities.Directories, existingFileWithContents.FileName)) { return(fullPathChanges.ShouldSkipLoadFileContents(fullPath)); //} } // Do the "expensive" check by going to the file system. var fi = _fileSystem.GetFileInfoSnapshot(fullPath); return ((fi.Exists) && (fi.IsFile) && (fi.LastWriteTimeUtc == existingFileWithContents.Contents.UtcLastModified)); }
public static int GetPrime(int min) { Invariants.CheckArgument(min >= 0, nameof(min), "Invalid prime seed"); for (int index = 0; index < Primes.Length; ++index) { int prime = Primes[index]; if (prime >= min) { return(prime); } } int candidate = min | 1; while (candidate < int.MaxValue) { if (IsPrime(candidate) && (candidate - 1) % 101 != 0) { return(candidate); } candidate += 2; } return(min); }
/// <summary> /// Returns a correct implementation of the persistence provider according to environment variables. /// </summary> /// <remarks>If the environment invariants have failed to hold upon creation of the storage provider, /// a <em>null</em> value will be provided.</remarks> public async Task <IStorageProvider> GetStorageProvider(string storageInvariant) { //Make sure the environment invariants hold before trying to give a functioning SUT instantiation. //This is done instead of the constructor to have more granularity on how the environment should be initialized. try { using (await StorageLock.LockAsync()) { if (AdoNetInvariants.Invariants.Contains(storageInvariant)) { if (!StorageProviders.ContainsKey(storageInvariant)) { Storage = Invariants.EnsureStorageForTesting(Invariants.ActiveSettings.ConnectionStrings.First(i => i.StorageInvariant == storageInvariant)); var properties = new Dictionary <string, string>(); properties["DataConnectionString"] = Storage.Storage.ConnectionString; properties["AdoInvariant"] = storageInvariant; var config = new ProviderConfiguration(properties, null); var storageProvider = new AdoNetStorageProvider(); await storageProvider.Init(storageInvariant + "_StorageProvider", DefaultProviderRuntime, config); StorageProviders[storageInvariant] = storageProvider; } } } } catch { StorageProviders.Add(storageInvariant, null); } return(StorageProviders[storageInvariant]); }
public BuildOutputSpan ParseFullPath(string text) { var match = _fullPathRegex.Value.Match(text); if (!match.Success) { return(null); } var filenameMatch = match.Groups["filename"]; var filename = filenameMatch.Value; Invariants.Assert(!string.IsNullOrEmpty(filename), "RegEx is malformed: it should not match an empty filename"); int line; int column; ParseLineColumn(match, out line, out column); return(new BuildOutputSpan { Text = text, Index = filenameMatch.Index, Length = match.Length - filenameMatch.Index, FileName = filename, LineNumber = line, ColumnNumber = column }); }
private bool IsFileContentsUpToDate(FileSystemEntities entities, FullPathChanges fullPathChanges, FileWithContents existingFileWithContents) { Invariants.Assert(existingFileWithContents.Contents != null); var fullPath = existingFileWithContents.FileName.FullPath; if (fullPathChanges != null) { // We don't get file change events for file in symlinks, so we can't // rely on fullPathChanges contents for our heuristic of avoiding file // system access. if (!FileDatabaseSnapshot.IsContainedInSymLinkHelper(entities.Directories, existingFileWithContents.FileName)) { return(fullPathChanges.ShouldSkipLoadFileContents(fullPath)); } } // Do the "expensive" check by going to the file system. var fi = _fileSystem.GetFileInfoSnapshot(fullPath); return ((fi.Exists) && (fi.IsFile) && (fi.LastWriteTimeUtc == existingFileWithContents.Contents.UtcLastModified)); }
public IFileDatabaseSnapshot BuildWithChangedFiles(IFileDatabaseSnapshot previousFileDatabaseSnapshot, FileSystemSnapshot fileSystemSnapshot, IEnumerable <ProjectFileName> changedFiles, Action onLoading, Action onLoaded, Action <IFileDatabaseSnapshot> onIntermadiateResult, CancellationToken cancellationToken) { using (new TimeElapsedLogger("Building file database from previous one and list of changed files", cancellationToken, InfoLogger.Instance)) { Invariants.Assert(previousFileDatabaseSnapshot is FileDatabaseSnapshot); var previousFileDatabase = (FileDatabaseSnapshot)previousFileDatabaseSnapshot; // Update file contents of file data entries of changed files. var filesToRead = changedFiles .Where(x => x.Project.IsFileSearchable(x.FileName) && previousFileDatabase.Files.ContainsKey(x.FileName)) .ToList(); if (filesToRead.Count == 0) { Logger.LogInfo("None of the changed file is searchable, return previous database snapshot"); return(previousFileDatabaseSnapshot); } // Read file contents. onLoading(); filesToRead.ForAll(x => { var newContents = _fileContentsFactory.ReadFileContents(x.FileName.FullPath); DangerousUpdateFileTableEntry(previousFileDatabase, x.FileName, newContents); }); onLoaded(); // Return new file database with updated file contents. return(new FileDatabaseSnapshot( previousFileDatabase.ProjectHashes, previousFileDatabase.Directories, previousFileDatabase.Files)); } }
/// <summary> /// Creates a <see cref="RelativePath"/> instance from a relative /// path string (e.g. "foo\\bar\\blah.txt"). /// </summary> public RelativePath(string relativePath) { Invariants.CheckArgumentNotNull(relativePath, nameof(relativePath)); Invariants.CheckArgument(!PathHelpers.IsAbsolutePath(relativePath), nameof(relativePath), "Path must be relative."); // Empty string is the same as the empty relative path _relativePath = relativePath == "" ? null : relativePath; }
private void LoadFileContents(FileSystemEntities entities, FileContentsLoadingContext loadingContext, CancellationToken cancellationToken) { using (new TimeElapsedLogger("Loading file contents from disk", cancellationToken)) { using (var progress = _progressTrackerFactory.CreateTracker(entities.Files.Count)) { entities.Files.AsParallelWrapper().ForAll(fileEntry => { Invariants.Assert(fileEntry.Value.Contents == null); // ReSharper disable once AccessToDisposedClosure if (progress.Step()) { // ReSharper disable once AccessToDisposedClosure progress.DisplayProgress((i, n) => string.Format("Reading file {0:n0} of {1:n0}: {2}", i, n, fileEntry.Value.FileName.FullPath)); // Check for cancellation if (cancellationToken.IsCancellationRequested) { loadingContext.PartialProgressReporter.ReportProgressNow(); cancellationToken.ThrowIfCancellationRequested(); } } var contents = LoadSingleFileContents(entities, loadingContext, fileEntry.Value); if (contents != null) { entities.Files[fileEntry.Key] = fileEntry.Value.WithContents(contents); } }); } } Logger.LogInfo("Loaded {0:n0} text files from disk, skipped {1:n0} binary files.", loadingContext.LoadedTextFileCount, loadingContext.LoadedBinaryFileCount); }
private void RunNextTaskIfAvailableAsync(TaskEntry task) { TaskEntryQueue.DequeueResult queueEntry; lock (_lock) { if (task == null) { // If there is a running task, bail, because we will be called again when the running task // finishes. if (_runningTask != null) { return; } } else { Invariants.Assert(ReferenceEquals(_runningTask, task)); } queueEntry = _taskQueue.Dequeue(_dateTimeProvider.UtcNow); _runningTask = queueEntry.TaskEntry; // May be null if only pdelayed tasks } if (queueEntry.TaskEntry != null) { // If there is a task available, run it RunTaskAsync(queueEntry.TaskEntry); } else if (queueEntry.HasPending) { // Run this method in a little while if there are pending tasks _customThreadPool.RunAsync(() => RunNextTaskIfAvailableAsync(null), TimeSpan.FromMilliseconds(50)); } }
private void RunTaskAsync(TaskEntry task) { Invariants.Assert(ReferenceEquals(_runningTask, task)); _customThreadPool.RunAsync(() => { Invariants.Assert(ReferenceEquals(_runningTask, task)); try { if (Logger.IsDebugEnabled) { Logger.LogDebug("Queue \"{0}\": Executing task \"{1}\" after waiting for {2:n0} msec", _description, task.Id.Description, (_dateTimeProvider.UtcNow - task.EnqueuedDateTimeUtc).TotalMilliseconds); } task.StopWatch.Start(); task.Action(_taskCancellationTracker.NewToken()); } finally { Invariants.Assert(ReferenceEquals(_runningTask, task)); task.StopWatch.Stop(); if (Logger.IsDebugEnabled) { Logger.LogDebug("Queue \"{0}\": Executed task \"{1}\" in {2:n0} msec", _description, task.Id.Description, task.StopWatch.ElapsedMilliseconds); } RunNextTaskIfAvailableAsync(task); } }); }
public static int WrapQueryStatus( IOleCommandTarget receiver, IOleCommandTarget implementer, ref System.Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, System.IntPtr pCmdText) { Invariants.Assert(receiver != null); var commandId = new CommandID(pguidCmdGroup, (int)prgCmds[0].cmdID); if (LogCommand(commandId)) { Logger.LogInfo("WrapQueryStatus: => recv={0}, impl={1}, parent={2}", receiver, GetImplementerString(implementer), GetParentTargetString(implementer)); } var hr = (implementer == null) ? (int)Constants.OLECMDERR_E_NOTSUPPORTED : implementer.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); if (LogCommand(commandId)) { Logger.LogInfo("WrapQueryStatus: <= recv={0}, impl={1}, parent={2}, hr={3}, cmdf={4}", receiver, GetImplementerString(implementer), GetParentTargetString(implementer), HrToString(hr), CmdFlagsToString(prgCmds)); } return(hr); }
private void ComputeNewStateLongTask(FileSystemSnapshot previousSnapshot, FileSystemSnapshot newSnapshot, FullPathChanges fullPathChanges, CancellationToken cancellationToken) { Invariants.Assert(_inTaskQueueTask); UpdateFileDatabase(newSnapshot, options => { // We only allow incremental updates if the last update was successfully completed // and if the file system snapshot version we are based on is the same as the // new file system snapshot we are processing if (previousSnapshot.Version == _currentFileSystemSnapshotVersion && options.PreviousUpdateCompleted && fullPathChanges != null) { return(CreateWithFileSystemChanges(newSnapshot, fullPathChanges, options, cancellationToken)); } else { Logger.LogInfo($"Starting a full database update: " + $"CurrentSnapshotVersion={_currentFileSystemSnapshotVersion}, " + $"PreviousUpdateCompleted={options.PreviousUpdateCompleted}, " + $"PreviousSnapshotVersion={previousSnapshot.Version}, " + $"FullPathChanges={fullPathChanges?.Entries.Count ?? -1}."); return(CreateFullScan(newSnapshot, options, cancellationToken)); } }); }
private IIncrementalHierarchyBuilder CreateIncrementalBuilder(FileSystemTree fileSystemTree) { var vsHierarchy = _hierarchy as VsHierarchy; if (vsHierarchy != null) { return(new IncrementalHierarchyBuilder( _nodeTemplateFactory, vsHierarchy, fileSystemTree, _imageSourceFactory)); } var vsHierarchyAggregate = _hierarchy as VsHierarchyAggregate; if (vsHierarchyAggregate != null) { return(new IncrementalHierarchyBuilderAggregate( _nodeTemplateFactory, vsHierarchyAggregate, fileSystemTree, _imageSourceFactory)); } Invariants.Assert(false); return(null); }
private IHierarchyObject PreviousSibling(IHierarchyObject item) { if (item == null) { return(null); } var parent = item.GetParent(); if (parent == null) { return(null); } IHierarchyObject previous = null; foreach (var child in parent.GetAllChildren()) { if (child.Equals(item)) { return(previous); } previous = child; } Invariants.Assert(false); return(null); }
private IHierarchyObject NextSibling(IHierarchyObject item) { if (item == null) { return(null); } var parent = item.GetParent(); if (parent == null) { return(null); } bool found = false; foreach (var child in parent.GetAllChildren()) { if (found) { return(child); } if (child.Equals(item)) { found = true; } } Invariants.Assert(found); return(null); }
public FileExtract FilePositionSpanToFileExtract(FilePositionSpan filePositionSpan, int maxTextExtent) { maxTextExtent = Math.Max(maxTextExtent, filePositionSpan.Length); var spanStart = filePositionSpan.Position; var spanEnd = spanStart + filePositionSpan.Length; var lineStart = GetLineStart(spanStart, maxTextExtent); var lineEnd = GetLineEnd(spanEnd, maxTextExtent); // prefix - span - suffix var extractLength = lineEnd - lineStart; var spanLength = filePositionSpan.Length; Invariants.Assert(spanLength <= extractLength); var prefixLength = Math.Min(spanStart - lineStart, maxTextExtent - spanLength); Invariants.Assert(prefixLength >= 0); var suffixLength = Math.Min(lineEnd - spanEnd, maxTextExtent - spanLength - prefixLength); Invariants.Assert(suffixLength >= 0); lineStart = spanStart - prefixLength; lineEnd = spanEnd + suffixLength; var text = GetText(lineStart, lineEnd - lineStart); var lineCol = GetLineColumn(spanStart); return(new FileExtract { Text = text, Offset = lineStart, Length = lineEnd - lineStart, LineNumber = lineCol.Item1, ColumnNumber = lineCol.Item2 }); }
internal LayerContext(Invariants invariants, Layer previousLayer, Layer currentLayer, int currentLayerIndex) { m_invariants = invariants; PreviousLayer = previousLayer; CurrentLayer = currentLayer; CurrentLayerIndex = currentLayerIndex; }
public static NodeViewModel CreateNodeViewModel(INodeTemplateFactory templateFactory, FileSystemEntry entry, NodeViewModel parent) { Invariants.Assert(entry != null); Invariants.Assert(parent != null); var directoryEntry = entry as DirectoryEntry; var node = directoryEntry != null ? (NodeViewModel) new DirectoryNodeViewModel(parent) : (NodeViewModel) new FileNodeViewModel(parent); node.Caption = entry.Name; node.Name = entry.Name; if (PathHelpers.IsAbsolutePath(node.Name)) { node.Template = templateFactory.ProjectTemplate; } else if (directoryEntry != null) { node.Template = templateFactory.DirectoryTemplate; } else { var extension = Path.GetExtension(entry.Name); Invariants.Assert(extension != null); node.Template = templateFactory.GetFileTemplate(extension); } return(node); }
private FileContents ReadFileContentsWorker(IFileInfoSnapshot fileInfo) { const int trailingByteCount = 2; var block = _fileSystem.ReadFileNulTerminated(fileInfo.Path, fileInfo.Length, trailingByteCount); var contentsByteCount = block.ByteLength - trailingByteCount; // Padding added by ReadFileNulTerminated var kind = NativeMethods.Text_GetKind(block.Pointer, contentsByteCount); switch (kind) { case NativeMethods.TextKind.TextKind_Ascii: // Note: Since we don't support UTF16 regex, just load all utf8 files as ascii. case NativeMethods.TextKind.TextKind_Utf8: return(new AsciiFileContents(new FileContentsMemory(block, 0, contentsByteCount), fileInfo.LastWriteTimeUtc)); case NativeMethods.TextKind.TextKind_AsciiWithUtf8Bom: // Note: Since we don't support UTF16 regex, just load all utf8 files as ascii. case NativeMethods.TextKind.TextKind_Utf8WithBom: const int utf8BomSize = 3; return(new AsciiFileContents(new FileContentsMemory(block, utf8BomSize, contentsByteCount - utf8BomSize), fileInfo.LastWriteTimeUtc)); #if false case NativeMethods.TextKind.TextKind_Utf8WithBom: var utf16Block = Conversion.UTF8ToUnicode(block); block.Dispose(); return(new Utf16FileContents(new FileContentsMemory(utf16Block, 0, utf16Block.ByteLength), fileInfo.LastWriteTimeUtc)); #endif case NativeMethods.TextKind.TextKind_ProbablyBinary: block.Dispose(); return(new BinaryFileContents(fileInfo.LastWriteTimeUtc, fileInfo.Length)); default: Invariants.Assert(false); throw new InvalidOperationException(); } }
public FileName(DirectoryName parent, string name) { Invariants.CheckArgumentNotNull(parent, nameof(parent)); Invariants.CheckArgumentNotNull(name, nameof(name), "File name is empty"); Invariants.CheckArgument(PathHelpers.IsFileName(name), nameof(name), "File name contains one or more directory separator"); _parent = parent; _name = name; }
private void ActivateCurrentDatabase(FileSystemSnapshot fileSystemSnapshot, IFileDatabaseSnapshot databaseSnapshot, bool complete) { Invariants.Assert(_inTaskQueueTask); _currentFileDatabase = databaseSnapshot; _currentFileSystemSnapshotVersion = fileSystemSnapshot.Version; _previousUpdateCompleted = complete; // Success => we allow incremtal updates next time }
public void TestLowBiasedQuery() { var random = new Random(42); var s = new SampleStream(Invariants.LowBiased(_relativeEpsilon)); var a = PopulateStream(s, random); VerifyLowPercsWithRelativeEpsilon(a, s); }
public static Invariants GetInvariants() { var db = new DbDataContext(); var ret = new Invariants(); ret.StructureTypes = db.StructureTypes.ToList(); ret.ShipTypes = db.ShipTypes.ToList(); ret.Technologies = db.Teches.ToList(); return ret; }
public void AddNode(NodeViewModel node) { Invariants.Assert(node.ItemId != VSConstants.VSITEMID_NIL); _itemIdMap.Add(node.ItemId, node); if (node.ItemId != RootNodeItemId) { _maxItemId = Math.Max(_maxItemId, node.ItemId); } }
public Func <int, ApplyChangesResult> ComputeChangeApplier() { // Capture hierarchy version # for checking later that another // thread did not beat us. int hierarchyVersion = _hierarchy.Version; var oldHierarchies = _hierarchy.CloneHierarchyList(); // For new hierarchies: create tree and compute nodes // For comon existing hierarchies: create tree and compute nodes // For removed hierarchies: create (empty) tree and compute nodes List <RootEntry> rootEntries = CreateRootEntries(oldHierarchies).ToList(); rootEntries.ForAll(entry => { entry.ChangeApplier = entry.Builder.ComputeChangeApplier(); }); return(latestFileSystemTreeVersion => { // Apply if nobody beat us to is. if (_hierarchy.Version == hierarchyVersion) { Logger.LogInfo( "Updating VsHierarchyAggregate nodes for version {0} and file system tree version {1}", hierarchyVersion, _fileSystemTree.Version); rootEntries.ForAll(entry => { var result = entry.ChangeApplier(latestFileSystemTreeVersion); Invariants.Assert(result == ApplyChangesResult.Done); }); var newHierarchies = rootEntries .Where(x => !x.Hierarchy.IsEmpty) .Select(x => x.Hierarchy) .ToList(); _hierarchy.SetNewHierarchies(newHierarchies); return ApplyChangesResult.Done; } Logger.LogInfo( "VsHierarchyAggregate nodes have been updated concurrently, re-run or skip operation." + " Node verions={0}-{1}, Tree versions:{2}-{3}.", hierarchyVersion, _hierarchy.Version, _fileSystemTree.Version, latestFileSystemTreeVersion); // If the version of the hieararchy has changed since when we started, // another thread has passed us. This means the decisions we made // about the changes to apply are incorrect at this point. So, we run // again if we are processing the latest known version of the file // system tree, as we should be the winner (eventually) if (_fileSystemTree.Version == latestFileSystemTreeVersion) { // Termination notes: We make this call only when the VsHierarchy // version changes between the time we capture it and this point. return ApplyChangesResult.Retry; } return ApplyChangesResult.Bail; }); }
public RelativeDirectoryName(DirectoryName parent, string name) { Invariants.CheckArgumentNotNull(parent, nameof(parent)); Invariants.CheckArgumentNotNull(name, nameof(name), "Directory name is empty"); Invariants.CheckArgument(PathHelpers.IsFileName(name), nameof(name), "Directory name contains one or more directory separator"); _parent = parent; _name = name; _hashCode = HashCode.Combine(_parent.GetHashCode(), SystemPathComparer.GetHashCode(_name)); }