diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java index 2957da5f21..b3dcb6629c 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponse.java @@ -298,6 +298,11 @@ public class MdnsResponse { return new LinkedList<>(records); } + /** Gets the number of records. */ + synchronized int getNumRecords() { + return records.size(); + } + /** * Drop address records if they are for a hostname that does not match the service record. * diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java index 1abad5e570..57449de769 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsResponseDecoder.java @@ -265,7 +265,7 @@ public class MdnsResponseDecoder { for (int i = 0; i < augmentedToOriginal.size(); i++) { final MdnsResponse augmented = augmentedToOriginal.keyAt(i); final MdnsResponse original = augmentedToOriginal.valueAt(i); - if (augmented.getRecords().size() != original.getRecords().size()) { + if (augmented.getNumRecords() != original.getNumRecords()) { modified.add(augmented); } } @@ -304,4 +304,4 @@ public class MdnsResponseDecoder { } return result == null ? List.of() : result; } -} \ No newline at end of file +} diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java index 3c13798fda..79fe7b182f 100644 --- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java +++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java @@ -59,14 +59,22 @@ public class MdnsServiceCache { public static class CacheKey { @NonNull final String mUpperCaseServiceType; @NonNull final SocketKey mSocketKey; + private final int mHashCode; CacheKey(@NonNull String serviceType, @NonNull SocketKey socketKey) { mUpperCaseServiceType = toDnsUpperCase(serviceType); mSocketKey = socketKey; + + // Equivalent to Objects.hash(mUpperCaseServiceType, mSocketKey), + // but without the unnecessary array allocation. + int hashCode = 1; + hashCode = 31 * hashCode + mUpperCaseServiceType.hashCode(); + hashCode = 31 * hashCode + mSocketKey.hashCode(); + mHashCode = hashCode; } @Override public int hashCode() { - return Objects.hash(mUpperCaseServiceType, mSocketKey); + return mHashCode; } @Override public boolean equals(Object other) { @@ -180,7 +188,8 @@ public class MdnsServiceCache { */ public static MdnsResponse findMatchedResponse(@NonNull List responses, @NonNull String serviceName) { - for (MdnsResponse response : responses) { + for (int i = 0; i < responses.size(); ++i) { + MdnsResponse response = responses.get(i); if (equalsIgnoreDnsCase(serviceName, response.getServiceInstanceName())) { return response; } @@ -190,7 +199,8 @@ public class MdnsServiceCache { private static CachedService findMatchedCachedService( @NonNull List cachedServices, @NonNull String serviceName) { - for (CachedService cachedService : cachedServices) { + for (int i = 0; i < cachedServices.size(); ++i) { + CachedService cachedService = cachedServices.get(i); if (equalsIgnoreDnsCase(serviceName, cachedService.mService.getServiceInstanceName())) { return cachedService; } diff --git a/service-t/src/com/android/server/connectivity/mdns/SocketKey.java b/service-t/src/com/android/server/connectivity/mdns/SocketKey.java index e6c06f55da..797cb656fb 100644 --- a/service-t/src/com/android/server/connectivity/mdns/SocketKey.java +++ b/service-t/src/com/android/server/connectivity/mdns/SocketKey.java @@ -40,6 +40,7 @@ public class SocketKey { */ @NonNull private final String mInterfaceName; + private final int mHashCode; SocketKey(int interfaceIndex, @NonNull String interfaceName) { this(null /* network */, interfaceIndex, interfaceName); @@ -49,6 +50,13 @@ public class SocketKey { mNetwork = network; mInterfaceIndex = interfaceIndex; mInterfaceName = interfaceName; + + // Equivalent to Objects.hash(mNetwork, mInterfaceIndex), but without + // the unnecessary array allocation. + int hashCode = 1; + hashCode = 31 * hashCode + (mNetwork == null ? 0 : mNetwork.hashCode()); + hashCode = 31 * hashCode + Integer.hashCode(mInterfaceIndex); + mHashCode = hashCode; } @Nullable @@ -67,7 +75,7 @@ public class SocketKey { @Override public int hashCode() { - return Objects.hash(mNetwork, mInterfaceIndex); + return mHashCode; } @Override diff --git a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java index df8d9f6030..f570282ebf 100644 --- a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java +++ b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java @@ -113,6 +113,16 @@ public final class CollectionUtils { return indexOf(elem, predicate) >= 0; } + /** + * @return True if any element satisfies the predicate, false otherwise. + * Note that means this always returns false for empty collections. + * + * This is an overload for List that avoids unnecessary iterator allocation. + */ + public static boolean any(@NonNull List elem, @NonNull Predicate predicate) { + return indexOf(elem, predicate) >= 0; + } + /** * @return The index of the first element that matches the predicate, or -1 if none. */ @@ -126,6 +136,21 @@ public final class CollectionUtils { return -1; } + /** + * @return The index of the first element that matches the predicate, or -1 if none. + * + * This is an overload for List that avoids unnecessary iterator allocation. + */ + public static int indexOf(@NonNull final List elem, + @NonNull final Predicate predicate) { + for (int idx = 0; idx < elem.size(); ++idx) { + if (predicate.test(elem.get(idx))) { + return idx; + } + } + return -1; + } + /** * @return True if there exists at least one element in the sparse array for which * condition {@code predicate} diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt index 84548fbe5d..2dfae4dfe9 100644 --- a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt +++ b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt @@ -53,6 +53,12 @@ class CollectionUtilsTest { assertEquals(1, CollectionUtils.indexOf(listOf("AA", "BBB", "CCCC")) { it.length >= 3 }) assertEquals(1, CollectionUtils.indexOf(listOf("AA", null, "CCCC")) { it == null }) assertEquals(1, CollectionUtils.indexOf(listOf(null, "CCCC")) { it != null }) + + assertEquals(4, CollectionUtils.indexOf(setOf("A", "B", "C", "D", "E")) { it == "E" }) + assertEquals(0, CollectionUtils.indexOf(setOf("A", "B", "C", "D", "E")) { it == "A" }) + assertEquals(1, CollectionUtils.indexOf(setOf("AA", "BBB", "CCCC")) { it.length >= 3 }) + assertEquals(1, CollectionUtils.indexOf(setOf("AA", null, "CCCC")) { it == null }) + assertEquals(1, CollectionUtils.indexOf(setOf(null, "CCCC")) { it != null }) } @Test