Skip to content

Commit

Permalink
Limit the maximum number of outline symbols to 5000 to avoid UI freezes
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Jun 21, 2023
1 parent 9ad25d4 commit c691bb6
Showing 1 changed file with 39 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@

public class SymbolsModel {

/**
* maximal number of symbols provided for the outline. limiting the number
* prevents the UI from freezing and becoming unusable.
*/
private static final int MAX_SYMBOLS = 5_000;

private static final SymbolInformation ROOT_SYMBOL_INFORMATION = new SymbolInformation();
private static final Object[] EMPTY = new Object[0];

Expand Down Expand Up @@ -112,24 +118,56 @@ public synchronized boolean update(List<Either<SymbolInformation, DocumentSymbol
final var parentStack = new ArrayDeque<SymbolInformation>();
parentStack.push(ROOT_SYMBOL_INFORMATION);
SymbolInformation previousSymbol = null;

int symbolsCount = 0;

for (Either<SymbolInformation, DocumentSymbol> either : response) {

if (symbolsCount >= MAX_SYMBOLS)
break;

// handle deprecated SymbolInformation elements
if (either.isLeft()) {
SymbolInformation symbol = either.getLeft();
if (isIncluded(previousSymbol, symbol)) {
parentStack.push(previousSymbol);
addChild(newChildrenMap, parentStack.peek(), symbol);
symbolsCount++;
} else if (isIncluded(parentStack.peek(), symbol)) {
addChild(newChildrenMap, parentStack.peek(), symbol);
symbolsCount++;
} else {
while (!isIncluded(parentStack.peek(), symbol)) {
parentStack.pop();
}
addChild(newChildrenMap, parentStack.peek(), symbol);
symbolsCount++;
parentStack.push(symbol);
}
previousSymbol = symbol;

// handle DocumentSymbol elements
} else if (either.isRight()) {
newRootSymbols.add(either.getRight());
final var docSym = either.getRight();
newRootSymbols.add(docSym);
symbolsCount++;

// count number of symbols and remove child symbols if MAX_SYMBOLS is reached
if (docSym.getChildren() != null) {
final var q = new ArrayDeque<DocumentSymbol>();
q.add(docSym);
while (!q.isEmpty()) {
final var parent = q.poll();
final var children = parent.getChildren();
if (children != null) {
if (symbolsCount + children.size() >= MAX_SYMBOLS) {
children.subList(MAX_SYMBOLS - symbolsCount, children.size()).clear();
}
symbolsCount += children.size();
q.addAll(children);
}
}
}
}
}

Expand Down

0 comments on commit c691bb6

Please sign in to comment.