public void Base() { int n = 100; int[] seq = new int[n]; rand.NextInts(seq); SparseTable <int> q1 = new SparseTable <int>(seq); int mini(int l, int r) { int ans = seq[l]; for (int i = l + 1; i < r; i++) { if (seq[i] < ans) { ans = seq[i]; } } return(ans); } for (int i = 0; i < n; i++) { int l = rand.Next(n - 1); int r = rand.Next(l + 1, n); Assert.AreEqual(mini(l, r), q1[l..r]);
private void UpdateSparseFolders(ITracer tracer, SparseTable sparseTable, string[] foldersToRemove, string[] foldersToAdd) { if (!this.ShowStatusWhileRunning( () => { foreach (string directoryPath in foldersToRemove) { tracer.RelatedInfo($"Removing '{directoryPath}' from sparse folders."); sparseTable.Remove(directoryPath); } foreach (string directoryPath in foldersToAdd) { tracer.RelatedInfo($"Adding '{directoryPath}' to sparse folders."); sparseTable.Add(directoryPath); } return(true); }, "Updating sparse folder set", suppressGvfsLogMessage: true)) { this.ReportErrorAndExit(tracer, "Failed to update sparse folder set."); } }
private string[] GetDirectoriesOutsideSparse(string rootPath, SparseTable sparseTable) { HashSet <string> sparseFolders = sparseTable.GetAll(); PhysicalFileSystem fileSystem = new PhysicalFileSystem(); Queue <string> foldersToEnumerate = new Queue <string>(); foldersToEnumerate.Enqueue(rootPath); List <string> foldersOutsideSparse = new List <string>(); while (foldersToEnumerate.Count > 0) { string folderToEnumerate = foldersToEnumerate.Dequeue(); foreach (string directory in fileSystem.EnumerateDirectories(folderToEnumerate)) { string enlistmentRootRelativeFolderPath = GVFSDatabase.NormalizePath(directory.Substring(rootPath.Length)); if (!enlistmentRootRelativeFolderPath.Equals(GVFSConstants.DotGit.Root, GVFSPlatform.Instance.Constants.PathComparison)) { if (sparseFolders.Any(x => x.StartsWith(enlistmentRootRelativeFolderPath + Path.DirectorySeparatorChar, GVFSPlatform.Instance.Constants.PathComparison))) { foldersToEnumerate.Enqueue(directory); } else if (!sparseFolders.Contains(enlistmentRootRelativeFolderPath)) { foldersOutsideSparse.Add(enlistmentRootRelativeFolderPath); } } } } return(foldersOutsideSparse.ToArray()); }
private string[] ParseFolderList(string folders) { if (string.IsNullOrEmpty(folders)) { return(new string[0]); } else { return(folders.Split(new[] { FolderListSeparator }, StringSplitOptions.RemoveEmptyEntries) .Select(x => SparseTable.NormalizePath(x)) .ToArray()); } }
private void ListSparseFolders(string enlistmentRoot) { using (GVFSDatabase database = new GVFSDatabase(new PhysicalFileSystem(), enlistmentRoot, new SqliteDatabase())) { SparseTable sparseTable = new SparseTable(database); HashSet <string> directories = sparseTable.GetAll(); if (directories.Count == 0) { this.Output.WriteLine("No folders in sparse list. When the sparse list is empty, all folders are projected."); } else { foreach (string directory in directories) { this.Output.WriteLine(directory); } } } }
public void Test() { var data = new int[,] { { 2, 3, 0, 1, 0 }, { 0, 3, 0, 0, 4 }, { 2, 0, 5, 0, 0 }, { 0, 0, 0, 5, 0 }, { 2, 0, 0, 0, 4 }, }; var table = new MutableTable<int>(data); var sparseTable = new SparseTable<int>(table); for (int r = 0; r != table.RowCount; ++r) for (int c = 0; c != table.ColumnCount; ++c) { Assert.AreEqual(table.Get(r, c), sparseTable.Get(r, c), "row=" + r +", col=" + c); } }
public void TestSparseTable() { var r = new Random(0); foreach (var length in new[] { 1, 2, 7, 8, 9, 31, 64, 127, 128, 129 }) { var data = CreateRandomIntArray(length, -100000, +100000, r); var min = SparseTable.Min(data); var max = SparseTable.Max(data); var minIndex = SparseTable.IndexOfMin(data); var maxIndex = SparseTable.IndexOfMax(data); for (int startIndex = 0; startIndex < data.Length; ++startIndex) { for (int endIndex = startIndex; endIndex < data.Length; ++endIndex) { Assert.AreEqual(SlowMinInInterval(data, startIndex, endIndex), min.Query(startIndex, endIndex)); Assert.AreEqual(SlowMaxInInterval(data, startIndex, endIndex), max.Query(startIndex, endIndex)); Assert.AreEqual(data[SlowMinIndexInInterval(data, startIndex, endIndex)], data[minIndex.Query(startIndex, endIndex)]); Assert.AreEqual(data[SlowMaxIndexInInterval(data, startIndex, endIndex)], data[maxIndex.Query(startIndex, endIndex)]); } } } }
public void Test() { var data = new int[, ] { { 2, 3, 0, 1, 0 }, { 0, 3, 0, 0, 4 }, { 2, 0, 5, 0, 0 }, { 0, 0, 0, 5, 0 }, { 2, 0, 0, 0, 4 }, }; var table = new MutableTable <int>(data); var sparseTable = new SparseTable <int>(table); for (int r = 0; r != table.RowCount; ++r) { for (int c = 0; c != table.ColumnCount; ++c) { Assert.AreEqual(table.Get(r, c), sparseTable.Get(r, c), "row=" + r + ", col=" + c); } } }
protected override void Execute(GVFSEnlistment enlistment) { using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, SparseVerbName)) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Sparse), EventLevel.Informational, Keywords.Any); bool needToChangeProjection = false; using (GVFSDatabase database = new GVFSDatabase(new PhysicalFileSystem(), enlistment.EnlistmentRoot, new SqliteDatabase())) { SparseTable sparseTable = new SparseTable(database); HashSet <string> directories = sparseTable.GetAll(); string[] foldersToRemove = this.ParseFolderList(this.Remove); string[] foldersToAdd = this.ParseFolderList(this.Add); if (this.List || (foldersToAdd.Length == 0 && foldersToRemove.Length == 0)) { if (directories.Count == 0) { this.Output.WriteLine("No folders in sparse list. When the sparse list is empty, all folders are projected."); } else { foreach (string directory in directories) { this.Output.WriteLine(directory); } } return; } foreach (string folder in foldersToRemove) { if (directories.Contains(folder)) { needToChangeProjection = true; break; } } if (!needToChangeProjection) { foreach (string folder in foldersToAdd) { if (!directories.Contains(folder)) { needToChangeProjection = true; break; } } } if (needToChangeProjection) { // Make sure there is a clean git status before allowing sparse set to change this.CheckGitStatus(tracer, enlistment); if (!this.ShowStatusWhileRunning( () => { foreach (string directoryPath in foldersToRemove) { tracer.RelatedInfo($"Removing '{directoryPath}' from sparse folders."); sparseTable.Remove(directoryPath); } foreach (string directoryPath in foldersToAdd) { tracer.RelatedInfo($"Adding '{directoryPath}' to sparse folders."); sparseTable.Add(directoryPath); } return(true); }, "Updating sparse folder set", suppressGvfsLogMessage: true)) { this.ReportErrorAndExit(tracer, "Failed to update sparse folder set."); } } } if (needToChangeProjection) { // Force a projection update to get the current inclusion set this.ForceProjectionChange(tracer, enlistment); tracer.RelatedInfo("Projection updated after adding or removing folders."); } else { this.WriteMessage(tracer, "No folders to update in sparse set."); } } }
public SparseReadOnlyTableGenerator(SparseTable<int> newTable, Pipe<EmitSyntax> ldRow, Pipe<EmitSyntax> ldCol) { this.table = newTable; this.LdRow = ldRow; this.LdCol = ldCol; }
private void PruneFoldersOutsideSparse(ITracer tracer, Enlistment enlistment, SparseTable sparseTable) { string[] directoriesToDehydrate = new string[0]; if (!this.ShowStatusWhileRunning( () => { directoriesToDehydrate = this.GetDirectoriesOutsideSparse(enlistment.WorkingDirectoryBackingRoot, sparseTable); return(true); }, $"Finding folders to {PruneOptionName}")) { this.ReportErrorAndExit(tracer, $"Failed to {PruneOptionName}."); } this.WriteMessage(tracer, $"Found {directoriesToDehydrate.Length} folders to {PruneOptionName}."); if (directoriesToDehydrate.Length > 0) { ReturnCode verbReturnCode = this.ExecuteGVFSVerb <DehydrateVerb>( tracer, verb => { verb.RunningVerbName = this.VerbName; verb.ActionName = PruneOptionName; verb.Confirmed = true; verb.Folders = string.Join(FolderListSeparator, directoriesToDehydrate); }, this.Output); if (verbReturnCode != ReturnCode.Success) { this.ReportErrorAndExit(tracer, verbReturnCode, $"Failed to {PruneOptionName}. Exit Code: {verbReturnCode}"); } } }
protected override void Execute(GVFSEnlistment enlistment) { if (this.List || ( !this.Prune && !this.Disable && string.IsNullOrEmpty(this.Add) && string.IsNullOrEmpty(this.Remove) && string.IsNullOrEmpty(this.Set) && string.IsNullOrEmpty(this.File))) { this.ListSparseFolders(enlistment.EnlistmentRoot); return; } this.CheckOptions(); using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, SparseVerbName)) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Sparse), EventLevel.Informational, Keywords.Any); EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(this.Set), this.Set); metadata.Add(nameof(this.File), this.File); metadata.Add(nameof(this.Add), this.Add); metadata.Add(nameof(this.Remove), this.Remove); metadata.Add(nameof(this.Prune), this.Prune); metadata.Add(nameof(this.Disable), this.Disable); tracer.RelatedInfo(metadata, $"Running sparse"); HashSet <string> directories; bool needToChangeProjection = false; using (GVFSDatabase database = new GVFSDatabase(new PhysicalFileSystem(), enlistment.EnlistmentRoot, new SqliteDatabase())) { SparseTable sparseTable = new SparseTable(database); directories = sparseTable.GetAll(); List <string> foldersToRemove = new List <string>(); List <string> foldersToAdd = new List <string>(); if (this.Disable) { if (directories.Count > 0) { this.WriteMessage(tracer, "Removing all folders from sparse list. When the sparse list is empty, all folders are projected."); needToChangeProjection = true; foldersToRemove.AddRange(directories); directories.Clear(); } else { return; } } else if (!string.IsNullOrEmpty(this.Set) || !string.IsNullOrEmpty(this.File)) { IEnumerable <string> folders = null; if (!string.IsNullOrEmpty(this.Set)) { folders = this.ParseFolderList(this.Set); } else if (!string.IsNullOrEmpty(this.File)) { PhysicalFileSystem fileSystem = new PhysicalFileSystem(); folders = this.ParseFolderList(fileSystem.ReadAllText(this.File), folderSeparator: Environment.NewLine); } else { this.WriteMessage(tracer, "Invalid options specified."); throw new InvalidOperationException(); } foreach (string folder in folders) { if (!directories.Contains(folder)) { needToChangeProjection = true; foldersToAdd.Add(folder); } else { // Remove from directories so that the only directories left in the directories collection // will be the ones that will need to be removed from sparse set directories.Remove(folder); } } if (directories.Count > 0) { needToChangeProjection = true; foldersToRemove.AddRange(directories); directories.Clear(); } // Need to add folders that will be in the projection back into directories for the status check foreach (string folder in folders) { directories.Add(folder); } } else { // Process adds and removes foreach (string folder in this.ParseFolderList(this.Remove)) { if (directories.Contains(folder)) { needToChangeProjection = true; directories.Remove(folder); foldersToRemove.Add(folder); } } foreach (string folder in this.ParseFolderList(this.Add)) { if (!directories.Contains(folder)) { needToChangeProjection = true; directories.Add(folder); foldersToAdd.Add(folder); } } } if (needToChangeProjection || this.Prune) { if (directories.Count > 0) { // Make sure there is a clean git status before allowing sparse set to change this.CheckGitStatus(tracer, enlistment, directories); } this.UpdateSparseFolders(tracer, sparseTable, foldersToRemove, foldersToAdd); } if (needToChangeProjection) { // Force a projection update to get the current inclusion set this.ForceProjectionChange(tracer, enlistment); tracer.RelatedInfo("Projection updated after adding or removing folders."); } else { this.WriteMessage(tracer, "No folders to update in sparse set."); } if (this.Prune && directories.Count > 0) { this.PruneFoldersOutsideSparse(tracer, enlistment, sparseTable); } } } }
private void PruneFoldersOutsideSparse(ITracer tracer, Enlistment enlistment, SparseTable sparseTable) { string[] directoriesToDehydrate = this.GetDirectoriesOutsideSparse(enlistment.WorkingDirectoryBackingRoot, sparseTable); if (directoriesToDehydrate.Length > 0) { if (!this.ShowStatusWhileRunning( () => { ReturnCode verbReturnCode = this.ExecuteGVFSVerb <DehydrateVerb>( tracer, verb => { verb.Confirmed = true; verb.Folders = string.Join(FolderListSeparator, directoriesToDehydrate); }); return(verbReturnCode == ReturnCode.Success); }, "Pruning folders")) { this.ReportErrorAndExit(tracer, "Failed to prune."); } } }
public SparseReadOnlyTableGenerator(SparseTable <int> newTable, Pipe <EmitSyntax> ldRow, Pipe <EmitSyntax> ldCol) { this.table = newTable; this.LdRow = ldRow; this.LdCol = ldCol; }