Skip to content

Commit

Permalink
File search: cache getMatchCount() result to avoid UI hangs
Browse files Browse the repository at this point in the history
If the search view has matches for 100.000 files, it would hang forever
on updating the view via F5 because it asks getMatchCount() for every
element and that traverses entire result again and again.

This change remembers last computed result and returns that value if
there were no further changes on the search result itself.

See #2279
  • Loading branch information
iloveeclipse committed Sep 24, 2024
1 parent aaf534a commit a8e99b2
Showing 1 changed file with 9 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public abstract class AbstractTextSearchResult implements ISearchResult {
private final ConcurrentMap<Object, Set<Match>> fElementsToMatches;
private final List<ISearchResultListener> fListeners;
private final MatchEvent fMatchEvent;
private volatile int matchCount;

private MatchFilter[] fMatchFilters;

Expand Down Expand Up @@ -157,6 +158,7 @@ private MatchEvent getSearchResultEvent(Collection<Match> matches, int eventKind

private boolean didAddMatch(Match match) {
updateFilterState(match);
matchCount = -1;
return fElementsToMatches.computeIfAbsent(match.getElement(), k -> ConcurrentHashMap.newKeySet()).add(match);
}

Expand All @@ -178,6 +180,7 @@ public void removeAll() {
fireChange(new RemoveAllEvent(this));
}
private void doRemoveAll() {
matchCount = 0;
fElementsToMatches.clear();
}

Expand Down Expand Up @@ -216,6 +219,7 @@ public void removeMatches(Match[] matches) {

private boolean didRemoveMatch(Match match) {
boolean[] existed = new boolean[1];
matchCount = -1;
fElementsToMatches.computeIfPresent(match.getElement(), (f, matches) -> {
existed[0] = matches.remove(match);
if (matches.isEmpty()) {
Expand Down Expand Up @@ -302,10 +306,14 @@ private boolean updateFilterState(Match match) {
* @return total number of matches
*/
public int getMatchCount() {
int count = 0;
int count = matchCount;
if (count != -1) {
return count;
}
for (Set<Match> element : fElementsToMatches.values()) {
count += element.size();
}
matchCount = count;
return count;
}

Expand Down

0 comments on commit a8e99b2

Please sign in to comment.