[updater] finds a nearest candidate for move

(improves over IDEA-CR-18874)
This commit is contained in:
Roman Shevchenko
2017-03-07 12:56:32 +01:00
parent 2f9f49599c
commit cf0760f62e
2 changed files with 40 additions and 15 deletions
@@ -44,20 +44,19 @@ public class DiffCalculator {
}
if (lookForMoved) {
Map<Long, String> byContent = inverse(result.filesToDelete);
Map<Long, List<String>> byContent = groupFilesByContent(result.filesToDelete);
Map<String, List<String>> byName = groupFilesByName(result.filesToDelete);
for (Map.Entry<String, Long> create : toCreate.entrySet()) {
if (Digester.isFile(create.getValue())) {
String source = byContent.get(create.getValue());
List<String> sameContent = byContent.get(create.getValue());
String source = findBestCandidateForMove(sameContent, create.getKey());
boolean move = true;
if (source == null || create.getKey().startsWith("jre")) {
if (source == null) {
List<String> sameName = byName.get(new File(create.getKey()).getName());
if (sameName != null) {
source = findBestCandidateForMove(sameName, create.getKey());
move = false;
}
source = findBestCandidateForMove(sameName, create.getKey());
move = false;
}
if (source != null && !critical.contains(source)) {
@@ -87,6 +86,8 @@ public class DiffCalculator {
}
private static String findBestCandidateForMove(List<String> paths, String path) {
if (paths == null) return null;
String best = "";
String[] dirs = path.split("/");
@@ -113,6 +114,20 @@ public class DiffCalculator {
return best;
}
public static Map<Long, List<String>> groupFilesByContent(Map<String, Long> map) {
Map<Long, List<String>> result = new HashMap<>();
for (Map.Entry<String, Long> entry : map.entrySet()) {
String path = entry.getKey();
if (!path.endsWith("/")) {
Long hash = entry.getValue();
List<String> paths = result.get(hash);
if (paths == null) result.put(hash, (paths = new LinkedList<>()));
paths.add(path);
}
}
return result;
}
private static Map<String, List<String>> groupFilesByName(Map<String, Long> toDelete) {
Map<String, List<String>> result = new HashMap<>();
for (String path : toDelete.keySet()) {
@@ -126,14 +141,6 @@ public class DiffCalculator {
return result;
}
public static Map<Long, String> inverse(Map<String, Long> map) {
Map<Long, String> inv = new LinkedHashMap<>();
for (Map.Entry<String, Long> entry : map.entrySet()) {
inv.put(entry.getValue(), entry.getKey());
}
return inv;
}
private static Map<String, Long> withAllRemoved(Map<String, Long> from, Map<String, Long> toRemove) {
Map<String, Long> result = new LinkedHashMap<>(from);
for (String each : toRemove.keySet()) {
@@ -225,6 +225,24 @@ public class PatchTest extends PatchTestCase {
CHECKSUMS.ANNOTATIONS_JAR));
}
@Test
public void testZipFileMoveWithAlternatives() throws Exception {
FileUtil.copy(new File(myOlderDir, "lib/annotations.jar"), new File(myOlderDir, "lib64/annotations.jar"));
FileUtil.delete(myNewerDir);
FileUtil.copyDir(myOlderDir, myNewerDir);
FileUtil.rename(new File(myNewerDir, "lib/annotations.jar"), new File(myNewerDir, "lib/redist/annotations.jar"));
FileUtil.rename(new File(myNewerDir, "lib64/annotations.jar"), new File(myNewerDir, "lib64/redist/annotations.jar"));
Patch patch = createPatch();
assertThat(sortActions(patch.getActions())).containsExactly(
new DeleteAction(patch, "lib/annotations.jar", CHECKSUMS.ANNOTATIONS_JAR),
new DeleteAction(patch, "lib64/annotations.jar", CHECKSUMS.ANNOTATIONS_JAR),
new CreateAction(patch, "lib/redist/"),
new CreateAction(patch, "lib64/redist/"),
new UpdateAction(patch, "lib/redist/annotations.jar", "lib/annotations.jar", CHECKSUMS.ANNOTATIONS_JAR, true),
new UpdateAction(patch, "lib64/redist/annotations.jar", "lib64/annotations.jar", CHECKSUMS.ANNOTATIONS_JAR, true));
}
@Test
public void testSaveLoad() throws Exception {
Patch original = createPatch();