-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
make desugar dependencies deterministic,
desugar dependencies are added to the result jar file as metadata, this desugar dependency object contain few list that we found out the order of this list can be different in different build with same inputs, therefore final result will have a different hash and it cause cache miss in the builds solution is to make the lists in this object sorted. so for the same input we always get same output
- Loading branch information
1 parent
1af61b2
commit 49e7027
Showing
5 changed files
with
241 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
.../google/devtools/build/android/desugar/dependencies/DesugarDependencyInfoWrapperTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.google.devtools.build.android.desugar.dependencies; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
|
||
import com.google.devtools.build.android.desugar.proto.DesugarDeps; | ||
|
||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.JUnit4; | ||
|
||
@RunWith(JUnit4.class) | ||
public class DesugarDependencyInfoWrapperTest { | ||
|
||
@Test | ||
public void testOrderForAssumeCompanionClass() throws Exception { | ||
DesugarDependencyInfoWrapper infoWrapper = new DesugarDependencyInfoWrapper(); | ||
infoWrapper.assumeCompanionClass(dependency("a", "b$$CC")); | ||
infoWrapper.assumeCompanionClass(dependency("b", "b$$CC")); | ||
infoWrapper.assumeCompanionClass(dependency("a", "a$$CC")); | ||
|
||
DesugarDeps.DesugarDepsInfo info = extractProto(infoWrapper); | ||
assertThat(info.getAssumePresentList().get(0)).isEqualTo(dependency("a", "a$$CC")); | ||
assertThat(info.getAssumePresentList().get(1)).isEqualTo(dependency("a", "b$$CC")); | ||
assertThat(info.getAssumePresentList().get(2)).isEqualTo(dependency("b", "b$$CC")); | ||
} | ||
|
||
@Test | ||
public void testMissingImplementedInterface() throws Exception { | ||
DesugarDependencyInfoWrapper infoWrapper = new DesugarDependencyInfoWrapper(); | ||
infoWrapper.missingImplementedInterface(dependency("a", "b$$CC")); | ||
infoWrapper.missingImplementedInterface(dependency("b", "b$$CC")); | ||
infoWrapper.missingImplementedInterface(dependency("a", "a$$CC")); | ||
|
||
DesugarDeps.DesugarDepsInfo info = extractProto(infoWrapper); | ||
assertThat(info.getMissingInterfaceList().get(0)).isEqualTo(dependency("a", "a$$CC")); | ||
assertThat(info.getMissingInterfaceList().get(1)).isEqualTo(dependency("a", "b$$CC")); | ||
assertThat(info.getMissingInterfaceList().get(2)).isEqualTo(dependency("b", "b$$CC")); | ||
} | ||
|
||
@Test | ||
public void testRecordExtendedInterfaces() throws Exception { | ||
DesugarDependencyInfoWrapper infoWrapper = new DesugarDependencyInfoWrapper(); | ||
|
||
infoWrapper.recordExtendedInterfaces(interfaceDetails("a")); | ||
infoWrapper.recordExtendedInterfaces(interfaceDetails("c")); | ||
infoWrapper.recordExtendedInterfaces(interfaceDetails("a")); | ||
|
||
DesugarDeps.DesugarDepsInfo info = extractProto(infoWrapper); | ||
assertThat(info.getInterfaceWithSupertypesList().get(0)).isEqualTo(interfaceDetails("a")); | ||
assertThat(info.getInterfaceWithSupertypesList().get(1)).isEqualTo(interfaceDetails("a")); | ||
assertThat(info.getInterfaceWithSupertypesList().get(2)).isEqualTo(interfaceDetails("c")); | ||
} | ||
|
||
@Test | ||
public void testRecordDefaultMethods() throws Exception { | ||
DesugarDependencyInfoWrapper infoWrapper = new DesugarDependencyInfoWrapper(); | ||
|
||
infoWrapper.recordDefaultMethods(interfaceWithCompanion("a",1)); | ||
infoWrapper.recordDefaultMethods(interfaceWithCompanion("c",2)); | ||
infoWrapper.recordDefaultMethods(interfaceWithCompanion("a",3)); | ||
|
||
DesugarDeps.DesugarDepsInfo info = extractProto(infoWrapper); | ||
assertThat(info.getInterfaceWithCompanionList().get(0)).isEqualTo(interfaceWithCompanion("a",1)); | ||
assertThat(info.getInterfaceWithCompanionList().get(1)).isEqualTo(interfaceWithCompanion("a",3)); | ||
assertThat(info.getInterfaceWithCompanionList().get(2)).isEqualTo(interfaceWithCompanion("c",2)); | ||
} | ||
|
||
private DesugarDeps.InterfaceWithCompanion interfaceWithCompanion(String origin, int count) { | ||
return DesugarDeps.InterfaceWithCompanion.newBuilder() | ||
.setOrigin(wrapType(origin)) | ||
.setNumDefaultMethods(count) | ||
.build(); | ||
} | ||
|
||
private DesugarDeps.InterfaceDetails interfaceDetails(String originName) { | ||
return DesugarDeps.InterfaceDetails.newBuilder().setOrigin(wrapType(originName)).build(); | ||
} | ||
|
||
private DesugarDeps.Dependency dependency(String origin, String target) { | ||
return DesugarDeps.Dependency.newBuilder() | ||
.setOrigin(wrapType(origin)) | ||
.setTarget(wrapType(target)) | ||
.build(); | ||
} | ||
|
||
private static DesugarDeps.Type wrapType(String name) { | ||
return DesugarDeps.Type.newBuilder().setBinaryName(name).build(); | ||
} | ||
|
||
private DesugarDeps.DesugarDepsInfo extractProto(DesugarDependencyInfoWrapper collector) | ||
throws Exception { | ||
return DesugarDeps.DesugarDepsInfo.parseFrom(collector.toByteArray()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
.../com/google/devtools/build/android/desugar/dependencies/DesugarDependencyInfoWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.google.devtools.build.android.desugar.dependencies; | ||
|
||
import com.google.devtools.build.android.desugar.proto.DesugarDeps; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Comparator; | ||
|
||
/** | ||
* a wrapper that is responsible to sort desugar dependency collector items since these items will | ||
* be add to the jar file as metadata it should be deterministic so that it won't cause cache misses | ||
*/ | ||
public class DesugarDependencyInfoWrapper { | ||
public final DesugarDeps.DesugarDepsInfo.Builder info = DesugarDeps.DesugarDepsInfo.newBuilder(); | ||
|
||
public ArrayList<DesugarDeps.Dependency> assumePresent = new ArrayList<>(); | ||
public ArrayList<DesugarDeps.Dependency> missingInterface = new ArrayList<>(); | ||
public ArrayList<DesugarDeps.InterfaceDetails> interfaceWithSupertypes = new ArrayList<>(); | ||
public ArrayList<DesugarDeps.InterfaceWithCompanion> interfaceWithCompanion = new ArrayList<>(); | ||
|
||
public void assumeCompanionClass(DesugarDeps.Dependency dependency) { | ||
assumePresent.add(dependency); | ||
} | ||
|
||
public void missingImplementedInterface(DesugarDeps.Dependency dependency) { | ||
missingInterface.add(dependency); | ||
} | ||
|
||
public void recordExtendedInterfaces(DesugarDeps.InterfaceDetails interfaceDetails) { | ||
interfaceWithSupertypes.add(interfaceDetails); | ||
} | ||
|
||
public void recordDefaultMethods(DesugarDeps.InterfaceWithCompanion interfaceWithCompanion) { | ||
this.interfaceWithCompanion.add(interfaceWithCompanion); | ||
} | ||
|
||
public byte[] toByteArray() { | ||
DesugarDeps.DesugarDepsInfo result = buildInfo(); | ||
return DesugarDeps.DesugarDepsInfo.getDefaultInstance().equals(result) | ||
? null | ||
: result.toByteArray(); | ||
} | ||
|
||
private DesugarDeps.DesugarDepsInfo buildInfo() { | ||
assumePresent.sort(dependencyComparator); | ||
missingInterface.sort(dependencyComparator); | ||
|
||
interfaceWithSupertypes.sort(interfaceDetailComparator); | ||
|
||
interfaceWithCompanion.sort(interFaceWithCompanionComparator); | ||
|
||
info.addAllAssumePresent(assumePresent); | ||
info.addAllMissingInterface(missingInterface); | ||
info.addAllInterfaceWithSupertypes(interfaceWithSupertypes); | ||
info.addAllInterfaceWithCompanion(interfaceWithCompanion); | ||
return info.build(); | ||
} | ||
|
||
Comparator<? super DesugarDeps.Dependency> dependencyComparator = | ||
Comparator.comparing((DesugarDeps.Dependency o) -> o.getOrigin().getBinaryName()) | ||
.thenComparing((DesugarDeps.Dependency o) -> o.getTarget().getBinaryName()); | ||
|
||
Comparator<? super DesugarDeps.InterfaceDetails> interfaceDetailComparator = | ||
Comparator.comparing((DesugarDeps.InterfaceDetails o) -> o.getOrigin().getBinaryName()); | ||
|
||
Comparator<? super DesugarDeps.InterfaceWithCompanion> interFaceWithCompanionComparator = | ||
Comparator.comparing(o -> o.getOrigin().getBinaryName()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters