Skip to content

Commit e01cd7c

Browse files
XenoAmessStuart Marks
authored and
Stuart Marks
committedJun 9, 2022
8284780: Need methods to create pre-sized HashSet and LinkedHashSet
Reviewed-by: naoto, bpb, dfuchs, ascarpino
1 parent a941bc2 commit e01cd7c

File tree

29 files changed

+147
-47
lines changed

29 files changed

+147
-47
lines changed
 

‎src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private PBEKeyFactory(String keytype) {
5656
}
5757

5858
static {
59-
validTypes = new HashSet<>(17);
59+
validTypes = HashSet.newHashSet(17);
6060
validTypes.add("PBEWithMD5AndDES".toUpperCase(Locale.ENGLISH));
6161
validTypes.add("PBEWithSHA1AndDESede".toUpperCase(Locale.ENGLISH));
6262
validTypes.add("PBEWithSHA1AndRC2_40".toUpperCase(Locale.ENGLISH));

‎src/java.base/share/classes/java/io/ObjectStreamClass.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ private static ObjectStreamField[] getDeclaredSerialFields(Class<?> cl)
16481648

16491649
ObjectStreamField[] boundFields =
16501650
new ObjectStreamField[serialPersistentFields.length];
1651-
Set<String> fieldNames = new HashSet<>(serialPersistentFields.length);
1651+
Set<String> fieldNames = HashSet.newHashSet(serialPersistentFields.length);
16521652

16531653
for (int i = 0; i < serialPersistentFields.length; i++) {
16541654
ObjectStreamField spf = serialPersistentFields[i];

‎src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ private Class<?> generateInnerClass() throws LambdaConversionException {
310310
interfaceNames = new String[]{interfaceName};
311311
} else {
312312
// Assure no duplicate interfaces (ClassFormatError)
313-
Set<String> itfs = new LinkedHashSet<>(altInterfaces.length + 1);
313+
Set<String> itfs = LinkedHashSet.newLinkedHashSet(altInterfaces.length + 1);
314314
itfs.add(interfaceName);
315315
for (Class<?> i : altInterfaces) {
316316
itfs.add(i.getName().replace('.', '/'));

‎src/java.base/share/classes/java/nio/charset/Charset.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ public final Set<String> aliases() {
718718
if (aliasSet != null)
719719
return aliasSet;
720720
int n = aliases.length;
721-
HashSet<String> hs = new HashSet<>(n);
721+
HashSet<String> hs = HashSet.newHashSet(n);
722722
for (int i = 0; i < n; i++)
723723
hs.add(aliases[i]);
724724
aliasSet = Collections.unmodifiableSet(hs);

‎src/java.base/share/classes/java/time/format/DecimalStyle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public final class DecimalStyle {
123123
*/
124124
public static Set<Locale> getAvailableLocales() {
125125
Locale[] l = DecimalFormatSymbols.getAvailableLocales();
126-
Set<Locale> locales = new HashSet<>(l.length);
126+
Set<Locale> locales = HashSet.newHashSet(l.length);
127127
Collections.addAll(locales, l);
128128
return locales;
129129
}

‎src/java.base/share/classes/java/util/Calendar.java

+1-8
Original file line numberDiff line numberDiff line change
@@ -2640,14 +2640,7 @@ public static Set<String> getAvailableCalendarTypes() {
26402640
}
26412641

26422642
private static class AvailableCalendarTypes {
2643-
private static final Set<String> SET;
2644-
static {
2645-
Set<String> set = new HashSet<>(3);
2646-
set.add("gregory");
2647-
set.add("buddhist");
2648-
set.add("japanese");
2649-
SET = Collections.unmodifiableSet(set);
2650-
}
2643+
private static final Set<String> SET = Set.of("gregory", "buddhist", "japanese");
26512644
private AvailableCalendarTypes() {
26522645
}
26532646
}

‎src/java.base/share/classes/java/util/HashSet.java

+25
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public HashSet(Collection<? extends E> c) {
125125
* Constructs a new, empty set; the backing {@code HashMap} instance has
126126
* the specified initial capacity and the specified load factor.
127127
*
128+
* @apiNote
129+
* To create a {@code HashSet} with an initial capacity that accommodates
130+
* an expected number of elements, use {@link #newHashSet(int) newHashSet}.
131+
*
128132
* @param initialCapacity the initial capacity of the hash map
129133
* @param loadFactor the load factor of the hash map
130134
* @throws IllegalArgumentException if the initial capacity is less
@@ -138,6 +142,10 @@ public HashSet(int initialCapacity, float loadFactor) {
138142
* Constructs a new, empty set; the backing {@code HashMap} instance has
139143
* the specified initial capacity and default load factor (0.75).
140144
*
145+
* @apiNote
146+
* To create a {@code HashSet} with an initial capacity that accommodates
147+
* an expected number of elements, use {@link #newHashSet(int) newHashSet}.
148+
*
141149
* @param initialCapacity the initial capacity of the hash table
142150
* @throws IllegalArgumentException if the initial capacity is less
143151
* than zero
@@ -372,4 +380,21 @@ public Object[] toArray() {
372380
public <T> T[] toArray(T[] a) {
373381
return map.keysToArray(map.prepareArray(a));
374382
}
383+
384+
/**
385+
* Creates a new, empty HashSet suitable for the expected number of elements.
386+
* The returned set uses the default load factor of 0.75, and its initial capacity is
387+
* generally large enough so that the expected number of elements can be added
388+
* without resizing the set.
389+
*
390+
* @param numElements the expected number of elements
391+
* @param <T> the type of elements maintained by the new set
392+
* @return the newly created set
393+
* @throws IllegalArgumentException if numElements is negative
394+
* @since 19
395+
*/
396+
public static <T> HashSet<T> newHashSet(int numElements) {
397+
return new HashSet<>(HashMap.calculateHashMapCapacity(numElements));
398+
}
399+
375400
}

‎src/java.base/share/classes/java/util/LinkedHashSet.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ public class LinkedHashSet<E>
126126
* Constructs a new, empty linked hash set with the specified initial
127127
* capacity and load factor.
128128
*
129+
* @apiNote
130+
* To create a {@code LinkedHashSet} with an initial capacity that accommodates
131+
* an expected number of elements, use {@link #newLinkedHashSet(int) newLinkedHashSet}.
132+
*
129133
* @param initialCapacity the initial capacity of the linked hash set
130134
* @param loadFactor the load factor of the linked hash set
131135
* @throws IllegalArgumentException if the initial capacity is less
@@ -139,6 +143,10 @@ public LinkedHashSet(int initialCapacity, float loadFactor) {
139143
* Constructs a new, empty linked hash set with the specified initial
140144
* capacity and the default load factor (0.75).
141145
*
146+
* @apiNote
147+
* To create a {@code LinkedHashSet} with an initial capacity that accommodates
148+
* an expected number of elements, use {@link #newLinkedHashSet(int) newLinkedHashSet}.
149+
*
142150
* @param initialCapacity the initial capacity of the LinkedHashSet
143151
* @throws IllegalArgumentException if the initial capacity is less
144152
* than zero
@@ -166,7 +174,7 @@ public LinkedHashSet() {
166174
* @throws NullPointerException if the specified collection is null
167175
*/
168176
public LinkedHashSet(Collection<? extends E> c) {
169-
super(Math.max(2*c.size(), 11), .75f, true);
177+
super(HashMap.calculateHashMapCapacity(Math.max(c.size(), 12)), .75f, true);
170178
addAll(c);
171179
}
172180

@@ -193,4 +201,21 @@ public LinkedHashSet(Collection<? extends E> c) {
193201
public Spliterator<E> spliterator() {
194202
return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
195203
}
204+
205+
/**
206+
* Creates a new, empty LinkedHashSet suitable for the expected number of elements.
207+
* The returned set uses the default load factor of 0.75, and its initial capacity is
208+
* generally large enough so that the expected number of elements can be added
209+
* without resizing the set.
210+
*
211+
* @param numElements the expected number of elements
212+
* @param <T> the type of elements maintained by the new set
213+
* @return the newly created set
214+
* @throws IllegalArgumentException if numElements is negative
215+
* @since 19
216+
*/
217+
public static <T> LinkedHashSet<T> newLinkedHashSet(int numElements) {
218+
return new LinkedHashSet<>(HashMap.calculateHashMapCapacity(numElements));
219+
}
220+
196221
}

‎src/java.base/share/classes/jdk/internal/module/ModuleInfo.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ private Builder readModuleAttribute(DataInput in, ConstantPool cpool, int major)
446446

447447
int exports_to_count = in.readUnsignedShort();
448448
if (exports_to_count > 0) {
449-
Set<String> targets = new HashSet<>(exports_to_count);
449+
Set<String> targets = HashSet.newHashSet(exports_to_count);
450450
for (int j=0; j<exports_to_count; j++) {
451451
int exports_to_index = in.readUnsignedShort();
452452
String target = cpool.getModuleName(exports_to_index);
@@ -486,7 +486,7 @@ private Builder readModuleAttribute(DataInput in, ConstantPool cpool, int major)
486486

487487
int open_to_count = in.readUnsignedShort();
488488
if (open_to_count > 0) {
489-
Set<String> targets = new HashSet<>(open_to_count);
489+
Set<String> targets = HashSet.newHashSet(open_to_count);
490490
for (int j=0; j<open_to_count; j++) {
491491
int opens_to_index = in.readUnsignedShort();
492492
String target = cpool.getModuleName(opens_to_index);
@@ -540,7 +540,7 @@ private Set<String> readModulePackagesAttribute(DataInput in, ConstantPool cpool
540540
throws IOException
541541
{
542542
int package_count = in.readUnsignedShort();
543-
Set<String> packages = new HashSet<>(package_count);
543+
Set<String> packages = HashSet.newHashSet(package_count);
544544
for (int i=0; i<package_count; i++) {
545545
int index = in.readUnsignedShort();
546546
String pn = cpool.getPackageName(index);

‎src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ private static Set<String> schemesListToSet(String list) {
278278
allowRestrictedHeaders = Boolean.parseBoolean(
279279
props.getProperty("sun.net.http.allowRestrictedHeaders"));
280280
if (!allowRestrictedHeaders) {
281-
restrictedHeaderSet = new HashSet<>(restrictedHeaders.length);
281+
restrictedHeaderSet = HashSet.newHashSet(restrictedHeaders.length);
282282
for (int i=0; i < restrictedHeaders.length; i++) {
283283
restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase());
284284
}

‎src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ private static class DefaultOptionsHolder {
230230
static final Set<SocketOption<?>> defaultOptions = defaultOptions();
231231

232232
private static Set<SocketOption<?>> defaultOptions() {
233-
HashSet<SocketOption<?>> set = new HashSet<>(2);
233+
HashSet<SocketOption<?>> set = HashSet.newHashSet(2);
234234
set.add(StandardSocketOptions.SO_RCVBUF);
235235
set.add(StandardSocketOptions.SO_REUSEADDR);
236236
if (Net.isReusePortAvailable()) {

‎src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ private static class DefaultOptionsHolder {
503503
static final Set<SocketOption<?>> defaultOptions = defaultOptions();
504504

505505
private static Set<SocketOption<?>> defaultOptions() {
506-
HashSet<SocketOption<?>> set = new HashSet<>(5);
506+
HashSet<SocketOption<?>> set = HashSet.newHashSet(5);
507507
set.add(StandardSocketOptions.SO_SNDBUF);
508508
set.add(StandardSocketOptions.SO_RCVBUF);
509509
set.add(StandardSocketOptions.SO_KEEPALIVE);

‎src/java.base/share/classes/sun/nio/fs/AbstractPoller.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ final WatchKey register(Path dir,
105105
// validate arguments before request to poller
106106
if (dir == null)
107107
throw new NullPointerException();
108-
Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
108+
Set<WatchEvent.Kind<?>> eventSet = HashSet.newHashSet(events.length);
109109
for (WatchEvent.Kind<?> event: events) {
110110
// standard events
111111
if (event == StandardWatchEventKinds.ENTRY_CREATE ||

‎src/java.base/share/classes/sun/nio/fs/PollingWatchService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ WatchKey register(final Path path,
9595
throws IOException
9696
{
9797
// check events - CCE will be thrown if there are invalid elements
98-
final Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
98+
final Set<WatchEvent.Kind<?>> eventSet = HashSet.newHashSet(events.length);
9999
for (WatchEvent.Kind<?> event: events) {
100100
// standard events
101101
if (event == StandardWatchEventKinds.ENTRY_CREATE ||

‎src/java.base/share/classes/sun/security/pkcs/PKCS7.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ public void encodeSignedData(DerOutputStream out)
514514
// CRLs (optional)
515515
if (crls != null && crls.length != 0) {
516516
// cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
517-
Set<X509CRLImpl> implCRLs = new HashSet<>(crls.length);
517+
Set<X509CRLImpl> implCRLs = HashSet.newHashSet(crls.length);
518518
for (X509CRL crl: crls) {
519519
if (crl instanceof X509CRLImpl)
520520
implCRLs.add((X509CRLImpl) crl);

‎src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public boolean isForwardCheckingSupported() {
9292
@Override
9393
public Set<String> getSupportedExtensions() {
9494
if (supportedExts == null) {
95-
supportedExts = new HashSet<String>(2);
95+
supportedExts = HashSet.newHashSet(2);
9696
supportedExts.add(BasicConstraints_Id.toString());
9797
supportedExts.add(NameConstraints_Id.toString());
9898
supportedExts = Collections.unmodifiableSet(supportedExts);

‎src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ final class ForwardBuilder extends Builder {
8181

8282
// populate sets of trusted certificates and subject DNs
8383
trustAnchors = buildParams.trustAnchors();
84-
trustedCerts = new HashSet<X509Certificate>(trustAnchors.size());
85-
trustedSubjectDNs = new HashSet<X500Principal>(trustAnchors.size());
84+
trustedCerts = HashSet.newHashSet(trustAnchors.size());
85+
trustedSubjectDNs = HashSet.newHashSet(trustAnchors.size());
8686
for (TrustAnchor anchor : trustAnchors) {
8787
X509Certificate trustedCert = anchor.getTrustedCert();
8888
if (trustedCert != null) {

‎src/java.base/share/classes/sun/security/provider/certpath/KeyChecker.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public boolean isForwardCheckingSupported() {
8585
@Override
8686
public Set<String> getSupportedExtensions() {
8787
if (supportedExts == null) {
88-
supportedExts = new HashSet<String>(3);
88+
supportedExts = HashSet.newHashSet(3);
8989
supportedExts.add(KeyUsage_Id.toString());
9090
supportedExts.add(ExtendedKeyUsage_Id.toString());
9191
supportedExts.add(SubjectAlternativeName_Id.toString());

‎src/java.base/share/classes/sun/security/provider/certpath/PolicyChecker.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class PolicyChecker extends PKIXCertPathChecker {
9393
if (initialPolicies.isEmpty()) {
9494
// if no initialPolicies are specified by user, set
9595
// initPolicies to be anyPolicy by default
96-
this.initPolicies = new HashSet<String>(1);
96+
this.initPolicies = HashSet.newHashSet(1);
9797
this.initPolicies.add(ANY_POLICY);
9898
} else {
9999
this.initPolicies = new HashSet<String>(initialPolicies);
@@ -154,7 +154,7 @@ public boolean isForwardCheckingSupported() {
154154
@Override
155155
public Set<String> getSupportedExtensions() {
156156
if (supportedExts == null) {
157-
supportedExts = new HashSet<String>(4);
157+
supportedExts = HashSet.newHashSet(4);
158158
supportedExts.add(CertificatePolicies_Id.toString());
159159
supportedExts.add(PolicyMappings_Id.toString());
160160
supportedExts.add(PolicyConstraints_Id.toString());

‎src/java.base/share/classes/sun/security/ssl/CertificateMessage.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ private static Collection<String> getSubjectAltNames(
573573
if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
574574
if (subAltDnsNames == null) {
575575
subAltDnsNames =
576-
new HashSet<>(subjectAltNames.size());
576+
HashSet.newHashSet(subjectAltNames.size());
577577
}
578578
subAltDnsNames.add(subAltDnsName);
579579
}

‎src/java.base/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private static class X509Credentials {
110110
// assert privateKey and certificates != null
111111
this.privateKey = privateKey;
112112
this.certificates = certificates;
113-
this.issuerX500Principals = new HashSet<>(certificates.length);
113+
this.issuerX500Principals = HashSet.newHashSet(certificates.length);
114114
for (X509Certificate certificate : certificates) {
115115
issuerX500Principals.add(certificate.getIssuerX500Principal());
116116
}

‎src/java.base/share/classes/sun/util/locale/InternalLocaleBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ private InternalLocaleBuilder setExtensions(List<String> bcpExtensions, String p
313313
clearExtensions();
314314

315315
if (!LocaleUtils.isEmpty(bcpExtensions)) {
316-
Set<CaseInsensitiveChar> done = new HashSet<>(bcpExtensions.size());
316+
Set<CaseInsensitiveChar> done = HashSet.newHashSet(bcpExtensions.size());
317317
for (String bcpExt : bcpExtensions) {
318318
CaseInsensitiveChar key = new CaseInsensitiveChar(bcpExt);
319319
// ignore duplicates

‎src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public OpeningHandshake(BuilderImpl b) {
148148
private static Collection<String> createRequestSubprotocols(
149149
Collection<String> subprotocols)
150150
{
151-
LinkedHashSet<String> sp = new LinkedHashSet<>(subprotocols.size(), 1);
151+
LinkedHashSet<String> sp = LinkedHashSet.newLinkedHashSet(subprotocols.size());
152152
for (String s : subprotocols) {
153153
if (s.trim().isEmpty() || !isValidName(s)) {
154154
throw illegal("Bad subprotocol syntax: " + s);

‎src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ private static Collection<TCPTransport> allKnownTransports() {
384384
Set<TCPTransport> s;
385385
synchronized (localEndpoints) {
386386
// presize s to number of localEndpoints
387-
s = new HashSet<TCPTransport>(localEndpoints.size());
387+
s = HashSet.newHashSet(localEndpoints.size());
388388
for (LinkedList<TCPEndpoint> epList : localEndpoints.values()) {
389389
/*
390390
* Each local endpoint has its transport added to s.

‎src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3309,7 +3309,7 @@ public byte[] comment() {
33093309
public Optional<Set<PosixFilePermission>> storedPermissions() {
33103310
Set<PosixFilePermission> perms = null;
33113311
if (posixPerms != -1) {
3312-
perms = new HashSet<>(PosixFilePermission.values().length);
3312+
perms = HashSet.newHashSet(PosixFilePermission.values().length);
33133313
for (PosixFilePermission perm : PosixFilePermission.values()) {
33143314
if ((posixPerms & ZipUtils.permToFlag(perm)) != 0) {
33153315
perms.add(perm);

‎test/jdk/java/io/RandomAccessFile/UnreferencedRAFClosesFd.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public static void main(String argv[]) throws Exception {
8181

8282
// Prepare to wait for FOS, FD, Cleanup to be reclaimed
8383
ReferenceQueue<Object> queue = new ReferenceQueue<>();
84-
HashSet<Reference<?>> pending = new HashSet<>(3);
84+
HashSet<Reference<?>> pending = HashSet.newHashSet(3);
8585
pending.add(new WeakReference<>(cleanup, queue));
8686
pending.add(new WeakReference<>(raf, queue));
8787
pending.add(new WeakReference<>(fd, queue));

‎test/jdk/java/lang/System/MacEncoding/TestFileEncoding.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public class TestFileEncoding {
5757
private String expectedEncoding; // Expected value for file.encoding
5858
private String langVar = null; // Value to set for LANG, etc
5959

60-
private static Set<String> envToRm = new HashSet<>(3);
60+
private static Set<String> envToRm = HashSet.newHashSet(3);
6161
static {
6262
// Take these vars out of the test's run environment, possibly adding
6363
// our own value back in.

‎test/jdk/java/text/Format/common/FormatIteratorTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ protected String escapeIfNecessary(String string) {
434434
}
435435

436436
public Set<Attribute> makeAttributes(List<Object> names) {
437-
Set<Attribute> set = new HashSet<>(Math.max(1, names.size()));
437+
Set<Attribute> set = HashSet.newHashSet(names.size());
438438

439439
for (int counter = 0; counter < names.size(); counter++) {
440440
set.add(makeAttribute((String)names.get(counter)));

‎test/jdk/java/util/HashMap/WhiteBoxResizeTest.java

+66-9
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@
2929
import java.lang.invoke.MethodHandles;
3030
import java.lang.invoke.MethodType;
3131
import java.lang.invoke.VarHandle;
32+
import java.lang.reflect.Field;
3233
import java.util.AbstractMap;
3334
import java.util.AbstractSet;
3435
import java.util.ArrayList;
3536
import java.util.Arrays;
3637
import java.util.HashMap;
38+
import java.util.HashSet;
3739
import java.util.Iterator;
3840
import java.util.LinkedHashMap;
41+
import java.util.LinkedHashSet;
3942
import java.util.List;
4043
import java.util.Map;
4144
import java.util.Set;
@@ -48,7 +51,7 @@
4851

4952
/*
5053
* @test
51-
* @bug 8186958 8210280 8281631 8285386
54+
* @bug 8186958 8210280 8281631 8285386 8284780
5255
* @modules java.base/java.util:open
5356
* @summary White box tests for HashMap-related internals around table sizing
5457
* @run testng/othervm -Xmx2g WhiteBoxResizeTest
@@ -58,6 +61,7 @@ public class WhiteBoxResizeTest {
5861
final MethodHandle TABLE_SIZE_FOR;
5962
final VarHandle HM_TABLE;
6063
final VarHandle WHM_TABLE;
64+
final VarHandle HS_MAP;
6165

6266
public WhiteBoxResizeTest() throws ReflectiveOperationException {
6367
MethodHandles.Lookup hmlookup = MethodHandles.privateLookupIn(HashMap.class, MethodHandles.lookup());
@@ -67,6 +71,9 @@ public WhiteBoxResizeTest() throws ReflectiveOperationException {
6771

6872
MethodHandles.Lookup whmlookup = MethodHandles.privateLookupIn(WeakHashMap.class, MethodHandles.lookup());
6973
WHM_TABLE = whmlookup.unreflectVarHandle(WeakHashMap.class.getDeclaredField("table"));
74+
75+
MethodHandles.Lookup hslookup = MethodHandles.privateLookupIn(HashSet.class, MethodHandles.lookup());
76+
HS_MAP = hslookup.unreflectVarHandle(HashSet.class.getDeclaredField("map"));
7077
}
7178

7279
/*
@@ -328,15 +335,17 @@ public void populatedCapacity(String label, // unused, included for diagnostics
328335
Object[] rsc(String label,
329336
int size,
330337
int expectedCapacity,
331-
Supplier<Map<String, String>> supplier) {
338+
Supplier<Capacitiable> supplier) {
332339
return new Object[]{label, size, expectedCapacity, supplier};
333340
}
334341

335342
List<Object[]> genRequestedSizeCases(int size, int cap) {
336343
return Arrays.asList(
337-
rsc("rshm", size, cap, () -> HashMap.newHashMap(size)),
338-
rsc("rslm", size, cap, () -> LinkedHashMap.newLinkedHashMap(size)),
339-
rsc("rswm", size, cap, () -> WeakHashMap.newWeakHashMap(size))
344+
rsc("rshm", size, cap, () -> new MapCapacitiable(HashMap.newHashMap(size))),
345+
rsc("rslm", size, cap, () -> new MapCapacitiable(LinkedHashMap.newLinkedHashMap(size))),
346+
rsc("rswm", size, cap, () -> new MapCapacitiable(WeakHashMap.newWeakHashMap(size))),
347+
rsc("rshs", size, cap, () -> new SetCapacitiable(HashSet.newHashSet(size))),
348+
rsc("rsls", size, cap, () -> new SetCapacitiable(LinkedHashSet.newLinkedHashSet(size)))
340349
);
341350
}
342351

@@ -364,9 +373,57 @@ public Iterator<Object[]> requestedSizeCases() {
364373
public void requestedSize(String label, // unused, included for diagnostics
365374
int size, // unused, included for diagnostics
366375
int expectedCapacity,
367-
Supplier<Map<String, String>> s) {
368-
Map<String, String> map = s.get();
369-
map.put("", "");
370-
assertEquals(capacity(map), expectedCapacity);
376+
Supplier<Capacitiable> s) {
377+
Capacitiable capacitiable = s.get();
378+
capacitiable.init();
379+
assertEquals(capacitiable.capacity(), expectedCapacity);
380+
}
381+
382+
interface Capacitiable {
383+
384+
void init();
385+
386+
int capacity();
387+
388+
}
389+
390+
class MapCapacitiable implements Capacitiable {
391+
392+
private final Map<String, String> content;
393+
394+
public MapCapacitiable(Map<String, String> content) {
395+
this.content = content;
396+
}
397+
398+
@Override
399+
public void init() {
400+
content.put("", "");
401+
}
402+
403+
@Override
404+
public int capacity() {
405+
return table(content).length;
406+
}
407+
}
408+
409+
class SetCapacitiable implements Capacitiable {
410+
411+
private final Set<String> content;
412+
413+
public SetCapacitiable(Set<String> content) {
414+
this.content = content;
415+
}
416+
417+
@Override
418+
public void init() {
419+
content.add("");
420+
}
421+
422+
@Override
423+
public int capacity() {
424+
HashMap<?, ?> hashMap = (HashMap<?, ?>) HS_MAP.get(content);
425+
return table(hashMap).length;
426+
}
371427
}
428+
372429
}

0 commit comments

Comments
 (0)
Please sign in to comment.