Skip to content

Commit

Permalink
Make the debounce adaptive for validation job (#1973)
Browse files Browse the repository at this point in the history
* Make the debounce adaptive for validation job

Signed-off-by: Sheng Chen <[email protected]>
  • Loading branch information
jdneo authored Dec 15, 2021
1 parent 4339d7c commit 238b06f
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2021 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.jdt.ls.core.internal;

/**
* A class used to calculate the cumulative moving average.
* @see <a href="https://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average">Definition from Wikipedia</a>.
*/
public class MovingAverage {
/**
* The average value
*/
public long value;

private long n = 1;

public MovingAverage() {
this(0);
}

/**
* Initialize the moving average with a initial value
* @param initValue The initial value of the moving average
*/
public MovingAverage(long initValue) {
this.value = initValue;
}

/**
* Update the moving average value
* @param value A new value used to update the moving average
* @return The <code>MovingAverage</code> instance
*/
public MovingAverage update(long value) {
this.value = this.value + (value - this.value) / this.n;
this.n += 1;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.JobHelpers;
import org.eclipse.jdt.ls.core.internal.MovingAverage;
import org.eclipse.jdt.ls.core.internal.corrections.DiagnosticsHelper;
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
import org.eclipse.jface.text.BadLocationException;
Expand All @@ -78,19 +79,28 @@ public abstract class BaseDocumentLifeCycleHandler {
public static final String DOCUMENT_LIFE_CYCLE_JOBS = "DocumentLifeCycleJobs";
public static final String PUBLISH_DIAGNOSTICS_JOBS = "DocumentLifeCyclePublishDiagnosticsJobs";

/**
* The max & init value of adaptive debounce time for document lifecycle job.
*/
private static final long DOCUMENT_LIFECYCLE_MAX_DEBOUNCE = 400; /*ms*/

private CoreASTProvider sharedASTProvider;
private WorkspaceJob validationTimer;
private WorkspaceJob publishDiagnosticsJob;
private Set<ICompilationUnit> toReconcile = new HashSet<>();
private Map<String, Integer> documentVersions = new HashMap<>();
private MovingAverage movingAverage = new MovingAverage(DOCUMENT_LIFECYCLE_MAX_DEBOUNCE);

public BaseDocumentLifeCycleHandler(boolean delayValidation) {
this.sharedASTProvider = CoreASTProvider.getInstance();
if (delayValidation) {
this.validationTimer = new WorkspaceJob("Validate documents") {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
return performValidation(monitor);
long start = System.currentTimeMillis();
IStatus status = performValidation(monitor);
movingAverage.update(System.currentTimeMillis() - start);
return status;
}

/* (non-Javadoc)
Expand Down Expand Up @@ -125,7 +135,7 @@ public boolean belongsTo(Object family) {
public abstract ICompilationUnit resolveCompilationUnit(String uri);

protected void triggerValidation(ICompilationUnit cu) throws JavaModelException {
triggerValidation(cu, 400);
triggerValidation(cu, getDocumentLifecycleDelay());
}

protected void triggerValidation(ICompilationUnit cu, long delay) throws JavaModelException {
Expand All @@ -150,6 +160,10 @@ protected void triggerValidation(ICompilationUnit cu, long delay) throws JavaMod
}
}

private long getDocumentLifecycleDelay() {
return Math.min(DOCUMENT_LIFECYCLE_MAX_DEBOUNCE, Math.round(1.5 * movingAverage.value));
}

private ISchedulingRule getRule(Set<ICompilationUnit> units) {
ISchedulingRule result = null;
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2021 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.jdt.ls.core.internal;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class MovingAverageTest {

@Test
public void testUpdate() {
MovingAverage average = new MovingAverage(400);

// initialize to 400 at first
assertEquals(400, average.value);

average.update(200);
// the first input value takes over the initial value
assertEquals(200, average.value);

average.update(100);
// (200 + 100) / 2
assertEquals(150, average.value);
}
}

0 comments on commit 238b06f

Please sign in to comment.