Merge "Switch GetDiff to use the new diff cache"

This commit is contained in:
Youssef Elghareeb
2021-03-18 08:45:49 +00:00
committed by Gerrit Code Review
7 changed files with 60 additions and 74 deletions

View File

@@ -19,13 +19,15 @@ import com.google.inject.AbstractModule;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
public class FileInfoJsonModule extends AbstractModule { public class FileInfoJsonModule extends AbstractModule {
/** Use the new diff cache implementation {@link FileInfoJsonNewImpl}. */
private final boolean useNewDiffCache; private final boolean useNewDiffCache;
/** Used to dark launch the new diff cache with the list files endpoint. */ /** Used to dark launch the new diff cache with the list files endpoint. */
private final boolean runNewDiffCacheAsync; private final boolean runNewDiffCacheAsync;
public FileInfoJsonModule(@GerritServerConfig Config cfg) { public FileInfoJsonModule(@GerritServerConfig Config cfg) {
this.useNewDiffCache = cfg.getBoolean("cache", "diff_cache", "useNewDiffCache", false); this.useNewDiffCache =
cfg.getBoolean("cache", "diff_cache", "runNewDiffCache_ListFiles", false);
this.runNewDiffCacheAsync = this.runNewDiffCacheAsync =
cfg.getBoolean("cache", "diff_cache", "runNewDiffCacheAsync_listFiles", false); cfg.getBoolean("cache", "diff_cache", "runNewDiffCacheAsync_listFiles", false);
} }

View File

@@ -82,8 +82,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
@Assisted("patchSetA") PatchSet.Id patchSetA, @Assisted("patchSetA") PatchSet.Id patchSetA,
@Assisted("patchSetB") PatchSet.Id patchSetB, @Assisted("patchSetB") PatchSet.Id patchSetB,
DiffPreferencesInfo diffPrefs, DiffPreferencesInfo diffPrefs,
CurrentUser currentUser, CurrentUser currentUser);
boolean useNewDiffCache);
PatchScriptFactory create( PatchScriptFactory create(
ChangeNotes notes, ChangeNotes notes,
@@ -91,8 +90,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
int parentNum, int parentNum,
PatchSet.Id patchSetB, PatchSet.Id patchSetB,
DiffPreferencesInfo diffPrefs, DiffPreferencesInfo diffPrefs,
CurrentUser currentUser, CurrentUser currentUser);
boolean useNewDiffCache);
} }
/** These metrics are temporary for launching the new redesigned diff cache. */ /** These metrics are temporary for launching the new redesigned diff cache. */
@@ -139,10 +137,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
private ChangeNotes notes; private ChangeNotes notes;
private final boolean runNewDiffCacheAsync; private final boolean runNewDiffCache;
// TODO(ghareeb): temporary field used for testing. Please remove.
private final boolean useNewDiffCache;
@AssistedInject @AssistedInject
PatchScriptFactory( PatchScriptFactory(
@@ -162,8 +157,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
@Assisted("patchSetA") @Nullable PatchSet.Id patchSetA, @Assisted("patchSetA") @Nullable PatchSet.Id patchSetA,
@Assisted("patchSetB") PatchSet.Id patchSetB, @Assisted("patchSetB") PatchSet.Id patchSetB,
@Assisted DiffPreferencesInfo diffPrefs, @Assisted DiffPreferencesInfo diffPrefs,
@Assisted CurrentUser currentUser, @Assisted CurrentUser currentUser) {
@Assisted boolean useNewDiffCache) {
this.repoManager = grm; this.repoManager = grm;
this.psUtil = psUtil; this.psUtil = psUtil;
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
@@ -183,9 +177,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
this.diffPrefs = diffPrefs; this.diffPrefs = diffPrefs;
this.currentUser = currentUser; this.currentUser = currentUser;
this.runNewDiffCacheAsync = this.runNewDiffCache = cfg.getBoolean("cache", "diff_cache", "runNewDiffCache_GetDiff", false);
cfg.getBoolean("cache", "diff_cache", "runNewDiffCacheAsync_getDiff", false);
this.useNewDiffCache = useNewDiffCache;
changeId = patchSetB.changeId(); changeId = patchSetB.changeId();
} }
@@ -208,8 +200,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
@Assisted int parentNum, @Assisted int parentNum,
@Assisted PatchSet.Id patchSetB, @Assisted PatchSet.Id patchSetB,
@Assisted DiffPreferencesInfo diffPrefs, @Assisted DiffPreferencesInfo diffPrefs,
@Assisted CurrentUser currentUser, @Assisted CurrentUser currentUser) {
@Assisted boolean useNewDiffCache) {
this.repoManager = grm; this.repoManager = grm;
this.psUtil = psUtil; this.psUtil = psUtil;
this.builderFactory = builderFactory; this.builderFactory = builderFactory;
@@ -229,9 +220,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
this.diffPrefs = diffPrefs; this.diffPrefs = diffPrefs;
this.currentUser = currentUser; this.currentUser = currentUser;
this.runNewDiffCacheAsync = this.runNewDiffCache = cfg.getBoolean("cache", "diff_cache", "runNewDiffCache_GetDiff", false);
cfg.getBoolean("cache", "diff_cache", "runNewDiffCacheAsync_getDiff", false);
this.useNewDiffCache = useNewDiffCache;
changeId = patchSetB.changeId(); changeId = patchSetB.changeId();
checkArgument(parentNum >= 0, "parentNum must be >= 0"); checkArgument(parentNum >= 0, "parentNum must be >= 0");
@@ -270,28 +259,15 @@ public class PatchScriptFactory implements Callable<PatchScript> {
} }
bId = edit.get().getEditCommit(); bId = edit.get().getEditCommit();
} }
if (runNewDiffCache) {
if (useNewDiffCache) { PatchScript patchScript = getPatchScriptWithNewDiffCache(git, aId, bId);
FileDiffOutput fileDiffOutput = // TODO(ghareeb): remove the async run. This is temporarily used to keep sanity checking
aId == null // the results while rolling out the new diff cache.
? diffOperations.getModifiedFileAgainstParent( runOldDiffCacheAsyncAndExportMetrics(git, aId, bId, patchScript);
notes.getProjectName(), return patchScript;
bId, } else {
parentNum == -1 ? null : parentNum + 1, return getPatchScriptWithOldDiffCache(git, aId, bId);
fileName,
diffPrefs.ignoreWhitespace)
: diffOperations.getModifiedFile(
notes.getProjectName(), aId, bId, fileName, diffPrefs.ignoreWhitespace);
return newBuilder().toPatchScriptNew(git, fileDiffOutput);
} }
PatchScriptBuilder patchScriptBuilder = newBuilder();
PatchList list = listFor(keyFor(aId, bId, diffPrefs.ignoreWhitespace));
PatchListEntry content = list.get(fileName);
PatchScript patchScript = patchScriptBuilder.toPatchScriptOld(git, list, content);
if (runNewDiffCacheAsync) {
runNewDiffCacheAsyncAndExportMetrics(git, aId, bId, patchScript);
}
return patchScript;
} catch (PatchListNotAvailableException e) { } catch (PatchListNotAvailableException e) {
throw new NoSuchChangeException(changeId, e); throw new NoSuchChangeException(changeId, e);
} catch (DiffNotAvailableException e) { } catch (DiffNotAvailableException e) {
@@ -311,24 +287,14 @@ public class PatchScriptFactory implements Callable<PatchScript> {
} }
} }
private void runNewDiffCacheAsyncAndExportMetrics( private void runOldDiffCacheAsyncAndExportMetrics(
Repository git, ObjectId aId, ObjectId bId, PatchScript expected) { Repository git, ObjectId aId, ObjectId bId, PatchScript expected) {
@SuppressWarnings("unused") @SuppressWarnings("unused")
Future<?> possiblyIgnoredError = Future<?> possiblyIgnoredError =
executor.submit( executor.submit(
() -> { () -> {
try { try {
FileDiffOutput fileDiffOutput = PatchScript patchScript = getPatchScriptWithOldDiffCache(git, aId, bId);
aId == null
? diffOperations.getModifiedFileAgainstParent(
notes.getProjectName(),
bId,
parentNum == -1 ? null : parentNum + 1,
fileName,
diffPrefs.ignoreWhitespace)
: diffOperations.getModifiedFile(
notes.getProjectName(), aId, bId, fileName, diffPrefs.ignoreWhitespace);
PatchScript patchScript = newBuilder().toPatchScriptNew(git, fileDiffOutput);
if (areEqualPatchscripts(patchScript, expected)) { if (areEqualPatchscripts(patchScript, expected)) {
metrics.diffs.increment(metrics.MATCH); metrics.diffs.increment(metrics.MATCH);
} else { } else {
@@ -337,7 +303,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
"Mismatching diff for change %s, old commit ID: %s, new commit ID: %s, file name: %s.", "Mismatching diff for change %s, old commit ID: %s, new commit ID: %s, file name: %s.",
changeId.toString(), aId, bId, fileName); changeId.toString(), aId, bId, fileName);
} }
} catch (DiffNotAvailableException | IOException e) { } catch (PatchListNotAvailableException | IOException e) {
metrics.diffs.increment(metrics.ERROR); metrics.diffs.increment(metrics.ERROR);
logger.atSevere().atMostEvery(10, TimeUnit.SECONDS).log( logger.atSevere().atMostEvery(10, TimeUnit.SECONDS).log(
String.format( String.format(
@@ -348,6 +314,29 @@ public class PatchScriptFactory implements Callable<PatchScript> {
}); });
} }
private PatchScript getPatchScriptWithOldDiffCache(Repository git, ObjectId aId, ObjectId bId)
throws IOException, PatchListNotAvailableException {
PatchScriptBuilder patchScriptBuilder = newBuilder();
PatchList list = listFor(keyFor(aId, bId, diffPrefs.ignoreWhitespace));
PatchListEntry content = list.get(fileName);
return patchScriptBuilder.toPatchScriptOld(git, list, content);
}
private PatchScript getPatchScriptWithNewDiffCache(Repository git, ObjectId aId, ObjectId bId)
throws IOException, DiffNotAvailableException {
FileDiffOutput fileDiffOutput =
aId == null
? diffOperations.getModifiedFileAgainstParent(
notes.getProjectName(),
bId,
parentNum == -1 ? null : parentNum + 1,
fileName,
diffPrefs.ignoreWhitespace)
: diffOperations.getModifiedFile(
notes.getProjectName(), aId, bId, fileName, diffPrefs.ignoreWhitespace);
return newBuilder().toPatchScriptNew(git, fileDiffOutput);
}
/** /**
* The comparison is not exhaustive but is using the most important fields. Comparing all fields * The comparison is not exhaustive but is using the most important fields. Comparing all fields
* will require some work in {@link PatchScript} to, e.g., convert it to autovalue. This * will require some work in {@link PatchScript} to, e.g., convert it to autovalue. This

View File

@@ -163,8 +163,7 @@ public class SubmitWithStickyApprovalDiff {
latestApprovedPatchsetId, latestApprovedPatchsetId,
currentPatchsetId, currentPatchsetId,
diffPreferencesInfo, diffPreferencesInfo,
currentUser, currentUser);
/* useNewDiffCache= */ false);
PatchScript patchScript = null; PatchScript patchScript = null;
try { try {
patchScript = patchScriptFactory.call(); patchScript = patchScriptFactory.call();

View File

@@ -91,10 +91,6 @@ public class GetDiff implements RestReadView<FileResource> {
@Option(name = "--intraline") @Option(name = "--intraline")
boolean intraline; boolean intraline;
// TODO(ghareeb): This is a temporary parameter for debugging. Please remove.
@Option(name = "--use-new-diff-cache")
boolean useNewDiffCache;
@Inject @Inject
GetDiff( GetDiff(
ProjectCache projectCache, ProjectCache projectCache,
@@ -143,15 +139,13 @@ public class GetDiff implements RestReadView<FileResource> {
} }
psf = psf =
patchScriptFactoryFactory.create( patchScriptFactoryFactory.create(
notes, fileName, basePatchSet.id(), pId, prefs, currentUser.get(), useNewDiffCache); notes, fileName, basePatchSet.id(), pId, prefs, currentUser.get());
} else if (parentNum > 0) { } else if (parentNum > 0) {
psf = psf =
patchScriptFactoryFactory.create( patchScriptFactoryFactory.create(
notes, fileName, parentNum - 1, pId, prefs, currentUser.get(), useNewDiffCache); notes, fileName, parentNum - 1, pId, prefs, currentUser.get());
} else { } else {
psf = psf = patchScriptFactoryFactory.create(notes, fileName, null, pId, prefs, currentUser.get());
patchScriptFactoryFactory.create(
notes, fileName, null, pId, prefs, currentUser.get(), useNewDiffCache);
} }
try { try {

View File

@@ -76,7 +76,7 @@ public class RevisionDiffIT extends AbstractDaemonTest {
private static final String FILE_CONTENT2 = "1st line\n2nd line\n3rd line\n"; private static final String FILE_CONTENT2 = "1st line\n2nd line\n3rd line\n";
private boolean intraline; private boolean intraline;
private boolean useNewDiffCache; private boolean useNewDiffCacheListFiles;
private boolean useNewDiffCacheGetDiff; private boolean useNewDiffCacheGetDiff;
private ObjectId commit1; private ObjectId commit1;
@@ -91,9 +91,10 @@ public class RevisionDiffIT extends AbstractDaemonTest {
baseConfig.setString("cache", "diff_intraline", "timeout", "1 minute"); baseConfig.setString("cache", "diff_intraline", "timeout", "1 minute");
intraline = baseConfig.getBoolean(TEST_PARAMETER_MARKER, "intraline", false); intraline = baseConfig.getBoolean(TEST_PARAMETER_MARKER, "intraline", false);
useNewDiffCache = baseConfig.getBoolean("cache", "diff_cache", "useNewDiffCache", false); useNewDiffCacheListFiles =
baseConfig.getBoolean("cache", "diff_cache", "runNewDiffCache_ListFiles", false);
useNewDiffCacheGetDiff = useNewDiffCacheGetDiff =
baseConfig.getBoolean("cache", "diff_cache", "useNewDiffCache_getDiff", false); baseConfig.getBoolean("cache", "diff_cache", "runNewDiffCache_GetDiff", false);
ObjectId headCommit = testRepo.getRepository().resolve("HEAD"); ObjectId headCommit = testRepo.getRepository().resolve("HEAD");
commit1 = commit1 =
@@ -1302,7 +1303,7 @@ public class RevisionDiffIT extends AbstractDaemonTest {
public void renamedUnrelatedFileIsIgnored_ForPatchSetDiffWithRebase_WhenEquallyModifiedInBoth() public void renamedUnrelatedFileIsIgnored_ForPatchSetDiffWithRebase_WhenEquallyModifiedInBoth()
throws Exception { throws Exception {
// TODO(ghareeb): fix this test for the new diff cache implementation // TODO(ghareeb): fix this test for the new diff cache implementation
assume().that(useNewDiffCache).isFalse(); assume().that(useNewDiffCacheListFiles).isFalse();
Function<String, String> contentModification = Function<String, String> contentModification =
fileContent -> fileContent.replace("1st line\n", "First line\n"); fileContent -> fileContent.replace("1st line\n", "First line\n");
@@ -1395,7 +1396,7 @@ public class RevisionDiffIT extends AbstractDaemonTest {
@Test @Test
public void filesTouchedByPatchSetsAndContainingOnlyRebaseHunksAreIgnored() throws Exception { public void filesTouchedByPatchSetsAndContainingOnlyRebaseHunksAreIgnored() throws Exception {
// TODO(ghareeb): fix this test for the new diff cache implementation // TODO(ghareeb): fix this test for the new diff cache implementation
assume().that(useNewDiffCache).isFalse(); assume().that(useNewDiffCacheListFiles).isFalse();
addModifiedPatchSet( addModifiedPatchSet(
changeId, FILE_NAME, fileContent -> fileContent.replace("Line 50\n", "Line fifty\n")); changeId, FILE_NAME, fileContent -> fileContent.replace("Line 50\n", "Line fifty\n"));
@@ -2777,7 +2778,7 @@ public class RevisionDiffIT extends AbstractDaemonTest {
@Test @Test
public void symlinkConvertedToRegularFileIsIdentifiedAsAdded() throws Exception { public void symlinkConvertedToRegularFileIsIdentifiedAsAdded() throws Exception {
// TODO(ghareeb): fix this test for the new diff cache implementation // TODO(ghareeb): fix this test for the new diff cache implementation
assume().that(useNewDiffCache).isFalse(); assume().that(useNewDiffCacheListFiles).isFalse();
assume().that(useNewDiffCacheGetDiff).isFalse(); assume().that(useNewDiffCacheGetDiff).isFalse();
String target = "file.txt"; String target = "file.txt";

View File

@@ -26,7 +26,7 @@ public class RevisionNewDiffCacheForSingleFileIT extends RevisionDiffIT {
@ConfigSuite.Default @ConfigSuite.Default
public static Config newDiffCacheConfig() { public static Config newDiffCacheConfig() {
Config config = new Config(); Config config = new Config();
config.setBoolean("cache", "diff_cache", "runNewDiffCacheAsync_getDiff", true); config.setBoolean("cache", "diff_cache", "runNewDiffCache_GetDiff", true);
return config; return config;
} }
} }

View File

@@ -18,14 +18,15 @@ import com.google.gerrit.testing.ConfigSuite;
import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config;
/** /**
* Runs the {@link RevisionDiffIT} tests with the new diff cache. This is temporary until the new * Runs the {@link RevisionDiffIT} with the list files endpoint using the new diff cache. This is
* diff cache is fully deployed. The new diff cache will become the default in the future. * temporary until the new diff cache is fully deployed. The new diff cache will become the default
* in the future.
*/ */
public class RevisionNewDiffCacheIT extends RevisionDiffIT { public class RevisionNewDiffCacheIT extends RevisionDiffIT {
@ConfigSuite.Default @ConfigSuite.Default
public static Config newDiffCacheConfig() { public static Config newDiffCacheConfig() {
Config config = new Config(); Config config = new Config();
config.setBoolean("cache", "diff_cache", "useNewDiffCache", true); config.setBoolean("cache", "diff_cache", "runNewDiffCache_ListFiles", true);
return config; return config;
} }
} }