# UNDF: UNDF-2026-000000706 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsResolveContext.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsResolveContext.java @@ -55,6 +55,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.LinkedHashSet; import java.util.Set; @@ -117,6 +118,8 @@ abstract class DnsResolveContext { private List finalResult; + // Tracks items already in finalResult for O(1) duplicate detection. + // Only allocated when isDuplicateAllowed() returns false (address resolution). + private Set finalResultSet; private int allowedQueries; private boolean triedCNAME; @@ -903,17 +906,15 @@ abstract class DnsResolveContext { if (!promise.isDone()) { - // We want to ensure we do not have duplicates in finalResult as this may be unexpected. - // - // While using a LinkedHashSet or HashSet may sound like the perfect fit for this we will use an - // ArrayList here as duplicates should be found quite unfrequently in the wild and we dont want to pay - // for the extra memory copy and allocations in this cases later on. if (finalResult == null) { finalResult = new ArrayList(8); + if (!isDuplicateAllowed()) { + finalResultSet = new LinkedHashSet(8); + } finalResult.add(converted); - } else if (isDuplicateAllowed() || !finalResult.contains(converted)) { + if (finalResultSet != null) { + finalResultSet.add(converted); + } + } else if (isDuplicateAllowed() || finalResultSet.add(converted)) { + // finalResultSet.add() returns false if already present: O(1) duplicate check finalResult.add(converted); } else { shouldRelease = true;