Skip to content

Commit

Permalink
[#932] prevent reconcile on every dirty region
Browse files Browse the repository at this point in the history
This change prevents reconcile run on every dirty region which can be
many thousands in a large source file (> 5000 lines) Since the
reconciler operate on the whole document it needed to be executed only
when the file document changes.

fixes #932
  • Loading branch information
ghentschke committed Mar 1, 2024
1 parent 8df7e08 commit 5e04ccf
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageServers;
import org.eclipse.lsp4e.internal.DocumentUtil;
import org.eclipse.lsp4j.FoldingRange;
import org.eclipse.lsp4j.FoldingRangeKind;
import org.eclipse.lsp4j.FoldingRangeRequestParams;
Expand All @@ -59,6 +60,7 @@ public class LSPFoldingReconcilingStrategy
private ProjectionAnnotationModel projectionAnnotationModel;
private ProjectionViewer viewer;
private @NonNull List<CompletableFuture<List<FoldingRange>>> requests = List.of();
private volatile long timestamp = 0;

/**
* A FoldingAnnotation is a {@link ProjectionAnnotation} it is folding and
Expand Down Expand Up @@ -312,7 +314,13 @@ protected void markInvalidAnnotationsForDeletion(List<FoldingAnnotation> deletio

@Override
public void reconcile(DirtyRegion dirtyRegion, IRegion partition) {
reconcile(dirtyRegion);
// Because a reconcile will be performed always on the whole document (this is specified by the LSP),
// prevent consecutive reconciling on every dirty region if the document has not changed.
var ts = DocumentUtil.getDocumentModificationStamp(document);
if (ts != timestamp) {
reconcile(dirtyRegion);
timestamp = ts;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public class SemanticHighlightReconcilerStrategy
*/
private volatile long documentTimestampAtLastAppliedTextPresentation;

private volatile long timestamp = 0;

private CompletableFuture<Optional<VersionedSemanticTokens>> semanticTokensFullFuture;

public SemanticHighlightReconcilerStrategy() {
Expand Down Expand Up @@ -291,12 +293,24 @@ public void initialReconcile() {

@Override
public void reconcile(final DirtyRegion dirtyRegion, final IRegion subRegion) {
fullReconcile();
fullReconcileOnce();
}

@Override
public void reconcile(final IRegion partition) {
fullReconcile();
fullReconcileOnce();
}

/**
* Because a full reconcile will be performed always on the whole document,
* prevent consecutive reconciling on dirty regions or partitions if the document has not changed.
*/
private void fullReconcileOnce() {
var ts = DocumentUtil.getDocumentModificationStamp(document);
if (ts != timestamp) {
fullReconcile();
timestamp = ts;
}
}

@Override
Expand Down

0 comments on commit 5e04ccf

Please sign in to comment.