Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2018-06-14 16:39:00 -0400
committerMatthias Sohn2018-06-16 03:45:45 -0400
commit5be233e1a7f05fd64dda12efa3128e6c13d236d3 (patch)
tree20b5100ab0616604d406a522d794d737ab2c1d20 /org.eclipse.egit.ui/src/org
parent14bf1114490d509b46c49524f85e2173e339081c (diff)
downloadegit-5be233e1a7f05fd64dda12efa3128e6c13d236d3.tar.gz
egit-5be233e1a7f05fd64dda12efa3128e6c13d236d3.tar.xz
egit-5be233e1a7f05fd64dda12efa3128e6c13d236d3.zip
Speed up staging view tree viewer management
In StagingView: 1. Don't call AbstractTreeViewer.getVisibleExpandedElements() multiple times. In fact, don't call it at all. We do have the tree hierarchy, and the tree viewer uses a hash map, so traversing the known sub- hierarchy explicitly is much faster. 2. Avoid duplicate paths to add (or remove) by using sets instead of lists. In StagingViewContentProvider: 3. Speed up getStagingEntriesFiltered and hasVisibleChildren by traversing the wanted sub-hierarchy explicitly. 4. Massively reduce the number of calls to getFilterPattern(). Bug:535856 Change-Id: I86876119c58f58305e722a832f8950c913d1f2d3 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.egit.ui/src/org')
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java36
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java50
2 files changed, 60 insertions, 26 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
index 20946407d..9f1e88978 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
@@ -3356,8 +3356,8 @@ public class StagingView extends ViewPart
StagingViewContentProvider contentProvider = getContentProvider(unstagedViewer);
final Repository repository = currentRepository;
Iterator iterator = selection.iterator();
- final List<String> addPaths = new ArrayList<>();
- final List<String> rmPaths = new ArrayList<>();
+ final Set<String> addPaths = new HashSet<>();
+ final Set<String> rmPaths = new HashSet<>();
resetPathsToExpand();
while (iterator.hasNext()) {
Object element = iterator.next();
@@ -3452,7 +3452,7 @@ public class StagingView extends ViewPart
}
private void selectEntryForStaging(StagingEntry entry,
- List<String> addPaths, List<String> rmPaths) {
+ Collection<String> addPaths, Collection<String> rmPaths) {
switch (entry.getState()) {
case ADDED:
case CHANGED:
@@ -3477,7 +3477,7 @@ public class StagingView extends ViewPart
if (selection.isEmpty())
return;
- final List<String> paths = processUnstageSelection(selection);
+ Collection<String> paths = processUnstageSelection(selection);
if (paths.isEmpty())
return;
@@ -3505,8 +3505,9 @@ public class StagingView extends ViewPart
schedule(resetJob, true);
}
- private List<String> processUnstageSelection(IStructuredSelection selection) {
- List<String> paths = new ArrayList<>();
+ private Collection<String> processUnstageSelection(
+ IStructuredSelection selection) {
+ Set<String> paths = new HashSet<>();
resetPathsToExpand();
for (Object element : selection.toList()) {
if (element instanceof StagingEntry) {
@@ -3526,7 +3527,7 @@ public class StagingView extends ViewPart
return paths;
}
- private void addUnstagePath(StagingEntry entry, List<String> paths) {
+ private void addUnstagePath(StagingEntry entry, Collection<String> paths) {
switch (entry.getState()) {
case ADDED:
case CHANGED:
@@ -3585,13 +3586,20 @@ public class StagingView extends ViewPart
private static void addExpandedPathsBelowFolder(StagingFolderEntry folder,
TreeViewer treeViewer, Set<IPath> addToSet) {
- Object[] expandedElements = treeViewer.getVisibleExpandedElements();
- for (Object expandedElement : expandedElements) {
- if (expandedElement instanceof StagingFolderEntry) {
- StagingFolderEntry expandedFolder = (StagingFolderEntry) expandedElement;
- if (folder.getPath().isPrefixOf(
- expandedFolder.getPath()))
- addPathAndParentPaths(expandedFolder.getPath(), addToSet);
+ if (treeViewer.getExpandedState(folder)) {
+ addPathAndParentPaths(folder.getPath(), addToSet);
+ }
+ addExpandedSubfolders(folder, treeViewer, addToSet);
+ }
+
+ private static void addExpandedSubfolders(StagingFolderEntry folder,
+ TreeViewer treeViewer, Set<IPath> addToSet) {
+ for (Object child : folder.getChildren()) {
+ if (child instanceof StagingFolderEntry
+ && treeViewer.getExpandedState(child)) {
+ addToSet.add(((StagingFolderEntry) child).getPath());
+ addExpandedSubfolders((StagingFolderEntry) child, treeViewer,
+ addToSet);
}
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
index 4612d9da0..9c276148c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
@@ -227,8 +227,9 @@ public class StagingViewContentProvider extends WorkbenchContentProvider {
} else {
int shownCount = 0;
for (StagingEntry entry : content) {
- if (isInFilter(entry))
+ if (matches(entry, filterPattern)) {
shownCount++;
+ }
}
return shownCount;
}
@@ -236,19 +237,28 @@ public class StagingViewContentProvider extends WorkbenchContentProvider {
List<StagingEntry> getStagingEntriesFiltered(StagingFolderEntry folder) {
List<StagingEntry> stagingEntries = new ArrayList<>();
- for (StagingEntry stagingEntry : content) {
- if (folder.getLocation().isPrefixOf(stagingEntry.getLocation())) {
- if (isInFilter(stagingEntry))
- stagingEntries.add(stagingEntry);
+ addFilteredDescendants(folder, getFilterPattern(), stagingEntries);
+ return stagingEntries;
+ }
+
+ private void addFilteredDescendants(StagingFolderEntry folder,
+ Pattern pattern, List<StagingEntry> result) {
+ for (Object child : folder.getChildren()) {
+ if (child instanceof StagingFolderEntry) {
+ addFilteredDescendants((StagingFolderEntry) child, pattern,
+ result);
+ } else if (matches((StagingEntry) child, pattern)) {
+ result.add((StagingEntry) child);
}
}
- return stagingEntries;
+ }
+
+ private boolean matches(StagingEntry entry, Pattern pattern) {
+ return pattern == null || pattern.matcher(entry.getPath()).find();
}
boolean isInFilter(StagingEntry stagingEntry) {
- Pattern filterPattern = getFilterPattern();
- return filterPattern == null
- || filterPattern.matcher(stagingEntry.getPath()).find();
+ return matches(stagingEntry, getFilterPattern());
}
private Pattern getFilterPattern() {
@@ -256,10 +266,26 @@ public class StagingViewContentProvider extends WorkbenchContentProvider {
}
boolean hasVisibleChildren(StagingFolderEntry folder) {
- if (getFilterPattern() == null)
+ Pattern pattern = getFilterPattern();
+ if (pattern == null) {
return true;
- else
- return !getStagingEntriesFiltered(folder).isEmpty();
+ }
+ return hasVisibleDescendants(folder, pattern);
+ }
+
+ private boolean hasVisibleDescendants(StagingFolderEntry folder,
+ Pattern pattern) {
+ for (Object child : folder.getChildren()) {
+ if (child instanceof StagingFolderEntry) {
+ if (hasVisibleDescendants((StagingFolderEntry) child,
+ pattern)) {
+ return true;
+ }
+ } else if (matches((StagingEntry) child, pattern)) {
+ return true;
+ }
+ }
+ return false;
}
StagingEntry[] getStagingEntries() {

Back to the top