From 96845ba265e6dc208c7ac96f5e58734209cd1720 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Mon, 27 Nov 2023 21:03:23 +0100 Subject: [PATCH] feat: Allow getting most common compatible versions for all packages --- .../kotlin/app/revanced/library/PatchUtils.kt | 48 ++++++++------- .../app/revanced/library/PatchUtilsTest.kt | 61 +++++++++++-------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/main/kotlin/app/revanced/library/PatchUtils.kt b/src/main/kotlin/app/revanced/library/PatchUtils.kt index de04dcd..83140c6 100644 --- a/src/main/kotlin/app/revanced/library/PatchUtils.kt +++ b/src/main/kotlin/app/revanced/library/PatchUtils.kt @@ -1,14 +1,14 @@ package app.revanced.library import app.revanced.patcher.PatchSet -import java.util.* +import app.revanced.patcher.patch.Patch -private typealias PackageName = String -private typealias Version = String -private typealias Count = Int +typealias PackageName = String +typealias Version = String +typealias Count = Int -private typealias VersionMap = SortedMap -internal typealias PackageNameMap = Map +typealias VersionMap = LinkedHashMap +typealias PackageNameMap = Map /** * Utility functions for working with patches. @@ -26,7 +26,7 @@ object PatchUtils { "Use getMostCommonCompatibleVersions instead.", ReplaceWith( "getMostCommonCompatibleVersions(patches, setOf(packageName))" + - ".entries.firstOrNull()?.value?.keys?.firstOrNull()", + ".entries.firstOrNull()?.value?.keys?.firstOrNull()", ), ) fun getMostCommonCompatibleVersion( @@ -48,30 +48,32 @@ object PatchUtils { * Get the count of versions for each compatible package from a supplied set of [patches] ordered by the most common version. * * @param patches The set of patches to check. - * @param packageNames The names of the compatible packages. + * @param packageNames The names of the compatible packages to include. If null, all packages will be included. * @param countUnusedPatches Whether to count patches that are not used. * @return A map of package names to a map of versions to their count. */ fun getMostCommonCompatibleVersions( patches: PatchSet, - packageNames: Set, + packageNames: Set? = null, countUnusedPatches: Boolean = false, - ): PackageNameMap { - val wantedPackages = packageNames.toHashSet() - return buildMap { - patches - .filter { it.use || countUnusedPatches } - .flatMap { it.compatiblePackages ?: emptyList() } - .filter { it.name in wantedPackages } - .forEach { compatiblePackage -> - compatiblePackage.versions?.let { versions -> - val versionMap = getOrPut(compatiblePackage.name) { sortedMapOf() } + ): PackageNameMap = buildMap { + fun filterWantedPackages(compatiblePackages: Iterable): Iterable { + val wantedPackages = packageNames?.toHashSet() ?: return compatiblePackages + return compatiblePackages.filter { it.name in wantedPackages } + } - versions.forEach { version -> - versionMap[version] = versionMap.getOrDefault(version, 0) + 1 - } + patches + .filter { it.use || countUnusedPatches } + .flatMap { it.compatiblePackages ?: emptyList() } + .let(::filterWantedPackages) + .forEach { compatiblePackage -> + val versionMap = getOrPut(compatiblePackage.name) { linkedMapOf() } + + compatiblePackage.versions?.let { versions -> + versions.forEach { version -> + versionMap[version] = versionMap.getOrDefault(version, 0) + 1 } } - } + } } } diff --git a/src/test/kotlin/app/revanced/library/PatchUtilsTest.kt b/src/test/kotlin/app/revanced/library/PatchUtilsTest.kt index 669c214..03e462e 100644 --- a/src/test/kotlin/app/revanced/library/PatchUtilsTest.kt +++ b/src/test/kotlin/app/revanced/library/PatchUtilsTest.kt @@ -25,43 +25,50 @@ internal object PatchUtilsTest { @Test fun `return common versions correctly ordered for each package`() { - assertEqualsVersions( + fun assertEqualsExpected(compatiblePackageNames: Set?) = assertEqualsVersions( expected = - mapOf( - "some.package" to sortedMapOf("a" to 3, "b" to 2, "c" to 1), - "some.other.package" to sortedMapOf("b" to 3, "c" to 2, "d" to 1), - "some.other.other.package" to sortedMapOf("a" to 1, "b" to 1), - "some.other.other.other.package" to sortedMapOf(), - ), + mapOf( + "some.package" to linkedMapOf("a" to 3, "b" to 2, "c" to 1), + "some.other.package" to linkedMapOf("b" to 3, "c" to 2, "d" to 1), + "some.other.other.package" to linkedMapOf("a" to 1, "b" to 1), + "some.other.other.other.package" to linkedMapOf(), + ), patches, - compatiblePackageNames = - setOf( - "some.package", - "some.other.package", - "some.other.other.package", - "some.other.other.other.package", - ), + compatiblePackageNames, countUnusedPatches = true, ) + + assertEqualsExpected( + compatiblePackageNames = setOf( + "some.package", + "some.other.package", + "some.other.other.package", + "some.other.other.other.package", + ), + ) + + assertEqualsExpected( + compatiblePackageNames = null + ) } @Test fun `return common versions correctly ordered for each package without counting unused patches`() { assertEqualsVersions( expected = - mapOf( - "some.package" to sortedMapOf("a" to 1), - "some.other.package" to sortedMapOf("b" to 2, "c" to 2, "d" to 1), - "some.other.other.package" to sortedMapOf("a" to 1, "b" to 1), - ), + mapOf( + "some.package" to linkedMapOf("a" to 1), + "some.other.package" to linkedMapOf("b" to 2, "c" to 2, "d" to 1), + "some.other.other.package" to linkedMapOf("a" to 1, "b" to 1), + ), patches, compatiblePackageNames = - setOf( - "some.package", - "some.other.package", - "some.other.other.package", - "some.other.other.other.package", - ), + setOf( + "some.package", + "some.other.package", + "some.other.other.package", + "some.other.other.other.package", + ), countUnusedPatches = false, ) } @@ -78,7 +85,7 @@ internal object PatchUtilsTest { @Test fun `return empty set of versions because no compatible package is constrained to a version`() { assertEqualsVersions( - expected = mapOf("some.package" to sortedMapOf()), + expected = mapOf("some.package" to linkedMapOf()), patches = setOf(newPatch("some.package")), compatiblePackageNames = setOf("some.package"), countUnusedPatches = true, @@ -121,7 +128,7 @@ internal object PatchUtilsTest { private fun assertEqualsVersions( expected: PackageNameMap, patches: PatchSet, - compatiblePackageNames: Set, + compatiblePackageNames: Set?, countUnusedPatches: Boolean = false, ) = assertEquals( expected,