Merge "Switch GetDiff to use the new diff cache"
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user