From c48d69362ee6135565d1366d4aa7b83dbf2d037e Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 14 May 2024 18:50:36 +0800 Subject: [PATCH] enhance: performance of filtering branch --- src/ViewModels/BranchTreeNode.cs | 68 +++++++++++++++++--------------- src/ViewModels/Repository.cs | 2 +- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/ViewModels/BranchTreeNode.cs b/src/ViewModels/BranchTreeNode.cs index 23e0b90a..b6b88b5d 100644 --- a/src/ViewModels/BranchTreeNode.cs +++ b/src/ViewModels/BranchTreeNode.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; - +using System.IO; using Avalonia.Collections; namespace SourceGit.ViewModels @@ -58,6 +58,8 @@ namespace SourceGit.ViewModels public void Run(List branches, List remotes, bool bForceExpanded) { + var folders = new Dictionary(); + foreach (var remote in remotes) { var path = $"remote/{remote.Name}"; @@ -69,7 +71,7 @@ namespace SourceGit.ViewModels IsExpanded = bForceExpanded || _expanded.Contains(path), }; - _maps.Add(path, node); + folders.Add(path, node); _remotes.Add(node); } @@ -78,16 +80,17 @@ namespace SourceGit.ViewModels var isFiltered = _filters.Contains(branch.FullName); if (branch.IsLocal) { - MakeBranchNode(branch, _locals, "local", isFiltered, bForceExpanded); + MakeBranchNode(branch, _locals, folders, "local", isFiltered, bForceExpanded); } else { var remote = _remotes.Find(x => x.Name == branch.Remote); if (remote != null) - MakeBranchNode(branch, remote.Children, $"remote/{remote.Name}", isFiltered, bForceExpanded); + MakeBranchNode(branch, remote.Children, folders, $"remote/{remote.Name}", isFiltered, bForceExpanded); } } + folders.Clear(); SortNodes(_locals); SortNodes(_remotes); } @@ -113,67 +116,69 @@ namespace SourceGit.ViewModels } } - private void MakeBranchNode(Models.Branch branch, List roots, string prefix, bool isFiltered, bool bForceExpanded) + private void MakeBranchNode(Models.Branch branch, List roots, Dictionary folders, string prefix, bool isFiltered, bool bForceExpanded) { - var subs = branch.Name.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - if (subs.Length == 1) + var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal); + if (sepIdx == -1) { - var node = new BranchTreeNode() + roots.Add(new BranchTreeNode() { - Name = subs[0], + Name = branch.Name, Type = BranchTreeNodeType.Branch, Backend = branch, IsExpanded = false, IsFiltered = isFiltered, - }; - roots.Add(node); + }); return; } - BranchTreeNode lastFolder = null; - var path = prefix; - for (var i = 0; i < subs.Length - 1; i++) + var lastFolder = null as BranchTreeNode; + var start = 0; + + while (sepIdx != -1) { - path = string.Concat(path, "/", subs[i]); - if (_maps.TryGetValue(path, out var value)) + var folder = string.Concat(prefix, "/", branch.Name.Substring(0, sepIdx)); + var name = branch.Name.Substring(start, sepIdx - start); + if (folders.TryGetValue(folder, out var val)) { - lastFolder = value; + lastFolder = val; } else if (lastFolder == null) { lastFolder = new BranchTreeNode() { - Name = subs[i], + Name = name, Type = BranchTreeNodeType.Folder, - IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(path), + IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), }; roots.Add(lastFolder); - _maps.Add(path, lastFolder); + folders.Add(folder, lastFolder); } else { - var folder = new BranchTreeNode() + var cur = new BranchTreeNode() { - Name = subs[i], + Name = name, Type = BranchTreeNodeType.Folder, - IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(path), + IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), }; - _maps.Add(path, folder); - lastFolder.Children.Add(folder); - lastFolder = folder; + lastFolder.Children.Add(cur); + folders.Add(folder, cur); + lastFolder = cur; } + + start = sepIdx + 1; + sepIdx = branch.Name.IndexOf('/', start); } - var last = new BranchTreeNode() + lastFolder.Children.Add(new BranchTreeNode() { - Name = subs[subs.Length - 1], + Name = Path.GetFileName(branch.Name), Type = BranchTreeNodeType.Branch, Backend = branch, IsExpanded = false, IsFiltered = isFiltered, - }; - lastFolder.Children.Add(last); + }); } private void SortNodes(List nodes) @@ -198,7 +203,6 @@ namespace SourceGit.ViewModels private readonly List _remotes = new List(); private readonly HashSet _expanded = new HashSet(); private readonly List _filters = new List(); - private readonly Dictionary _maps = new Dictionary(); } } } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 8a81c595..1f061b02 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1389,7 +1389,7 @@ namespace SourceGit.ViewModels visibles.Add(b); } - builder.Run(visibles, remotes, true); + builder.Run(visibles, remotes, visibles.Count <= 20); } return builder;