8338060: jdk/internal/util/ReferencedKeyTest should be more robust
Reviewed-by: never
This commit is contained in:
parent
41e31d6b0a
commit
b93b74e3eb
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8285932 8310913
|
||||
* @bug 8285932 8310913 8336390 8338060
|
||||
* @summary Test features provided by the ReferencedKeyMap/ReferencedKeySet classes.
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @compile --patch-module java.base=${test.src} ReferencedKeyTest.java
|
||||
@ -36,14 +36,27 @@ import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ReferencedKeyTest {
|
||||
static long BASE_KEY = 10_000_000L;
|
||||
private static String BASE_KEY = "BASEKEY-";
|
||||
|
||||
// Return a String (identity object) that can be a key in WeakHashMap.
|
||||
private static String genKey(int i) {
|
||||
return BASE_KEY + i;
|
||||
}
|
||||
|
||||
// Return a String of the letter 'a' plus the integer (0..0xffff)
|
||||
private static String genValue(int i) {
|
||||
return String.valueOf((char) ('a' + i));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
mapTest(false, HashMap::new);
|
||||
@ -63,73 +76,77 @@ public class ReferencedKeyTest {
|
||||
}
|
||||
}
|
||||
|
||||
static void mapTest(boolean isSoft, Supplier<Map<ReferenceKey<Long>, String>> supplier) {
|
||||
Map<Long, String> map = ReferencedKeyMap.create(isSoft, supplier);
|
||||
populate(map);
|
||||
static void mapTest(boolean isSoft, Supplier<Map<ReferenceKey<String>, String>> supplier) {
|
||||
Map<String, String> map = ReferencedKeyMap.create(isSoft, supplier);
|
||||
var strongKeys = populate(map); // Retain references to the keys
|
||||
methods(map);
|
||||
Reference.reachabilityFence(strongKeys);
|
||||
|
||||
strongKeys = null; // drop strong key references
|
||||
if (!isSoft) {
|
||||
if (!collect(() -> map.isEmpty())) {
|
||||
throw new RuntimeException("WeakReference map not collecting!");
|
||||
}
|
||||
}
|
||||
populate(map);
|
||||
methods(map);
|
||||
}
|
||||
|
||||
static void setTest(boolean isSoft, Supplier<Map<ReferenceKey<Long>, ReferenceKey<Long>>> supplier) {
|
||||
ReferencedKeySet<Long> set = ReferencedKeySet.create(isSoft, supplier);
|
||||
populate(set);
|
||||
static void setTest(boolean isSoft, Supplier<Map<ReferenceKey<String>, ReferenceKey<String>>> supplier) {
|
||||
ReferencedKeySet<String> set = ReferencedKeySet.create(isSoft, supplier);
|
||||
var strongKeys = populate(set); // Retain references to the keys
|
||||
methods(set);
|
||||
Reference.reachabilityFence(strongKeys);
|
||||
|
||||
strongKeys = null; // drop strong key references
|
||||
if (!isSoft) {
|
||||
if (!collect(() -> set.isEmpty())) {
|
||||
throw new RuntimeException("WeakReference set not collecting!");
|
||||
}
|
||||
}
|
||||
populate(set);
|
||||
methods(set);
|
||||
}
|
||||
|
||||
static void methods(Map<Long, String> map) {
|
||||
static void methods(Map<String, String> map) {
|
||||
assertTrue(map.size() == 26, "missing key");
|
||||
assertTrue(map.containsKey(BASE_KEY + 'a' -'a'), "missing key");
|
||||
assertTrue(map.get(BASE_KEY + 'b' -'a').equals("b"), "wrong key");
|
||||
assertTrue(map.containsKey(genKey('a' -'a')), "missing key");
|
||||
assertTrue(map.get(genKey('b' -'a')).equals("b"), "wrong key");
|
||||
assertTrue(map.containsValue("c"), "missing value");
|
||||
map.remove(BASE_KEY + 'd' -'a');
|
||||
assertTrue(map.get(BASE_KEY + 'd' -'a') == null, "not removed");
|
||||
map.putAll(Map.of(1L, "A", 2L, "B"));
|
||||
assertTrue(map.get(2L).equals("B"), "collection not added");
|
||||
assertTrue(map.containsKey(1L), "key missing");
|
||||
map.remove(genKey('d' -'a'));
|
||||
assertTrue(map.get(genKey('d' -'a')) == null, "not removed");
|
||||
map.putAll(Map.of(genKey(1), "A", genKey(2), "B"));
|
||||
assertTrue(map.get(genKey(2)).equals("B"), "collection not added");
|
||||
assertTrue(map.containsKey(genKey(1)), "key missing");
|
||||
assertTrue(map.containsValue("A"), "key missing");
|
||||
assertTrue(map.entrySet().contains(Map.entry(1L, "A")), "key missing");
|
||||
map.putIfAbsent(3L, "C");
|
||||
assertTrue(map.get(3L).equals("C"), "key missing");
|
||||
map.putIfAbsent(2L, "D");
|
||||
assertTrue(map.get(2L).equals("B"), "key replaced");
|
||||
map.remove(3L);
|
||||
assertTrue(map.get(3L) == null, "key not removed");
|
||||
map.replace(2L, "D");
|
||||
assertTrue(map.get(2L).equals("D"), "key not replaced");
|
||||
map.replace(2L, "B", "E");
|
||||
assertTrue(map.get(2L).equals("D"), "key replaced");
|
||||
assertTrue(map.entrySet().contains(Map.entry(genKey(1), "A")), "key missing");
|
||||
map.putIfAbsent(genKey(3), "C");
|
||||
assertTrue(map.get(genKey(3)).equals("C"), "key missing");
|
||||
map.putIfAbsent(genKey(2), "D");
|
||||
assertTrue(map.get(genKey(2)).equals("B"), "key replaced");
|
||||
map.remove(genKey(3));
|
||||
assertTrue(map.get(genKey(3)) == null, "key not removed");
|
||||
map.replace(genKey(2), "D");
|
||||
assertTrue(map.get(genKey(2)).equals("D"), "key not replaced");
|
||||
map.replace(genKey(2), "B", "E");
|
||||
assertTrue(map.get(genKey(2)).equals("D"), "key replaced");
|
||||
}
|
||||
|
||||
static void methods(ReferencedKeySet<Long> set) {
|
||||
static void methods(ReferencedKeySet<String> set) {
|
||||
assertTrue(set.size() == 26, "missing key");
|
||||
assertTrue(set.contains(BASE_KEY + 3), "missing key");
|
||||
set.remove(BASE_KEY + 3);
|
||||
assertTrue(!set.contains(BASE_KEY + 3), "not removed");
|
||||
Long element1 = set.get(BASE_KEY + 2);
|
||||
Long element2 = set.get(BASE_KEY + 3);
|
||||
Long element3 = set.get(BASE_KEY + 4);
|
||||
Long intern1 = set.intern(BASE_KEY + 2);
|
||||
Long intern2 = set.intern(BASE_KEY + 3);
|
||||
Long intern3 = set.intern(BASE_KEY + 4, e -> e);
|
||||
assertTrue(set.contains(genKey(3)), "missing key");
|
||||
set.remove(genKey(3));
|
||||
assertTrue(!set.contains(genKey(3)), "not removed");
|
||||
String element1 = set.get(genKey(2));
|
||||
String element2 = set.get(genKey(3));
|
||||
String element3 = set.get(genKey(4));
|
||||
String intern1 = set.intern(genKey(2));
|
||||
String intern2 = set.intern(genKey(3));
|
||||
String intern3 = set.intern(genKey(4), e -> e);
|
||||
assertTrue(element1 != null, "missing key");
|
||||
assertTrue(element2 == null, "not removed");
|
||||
assertTrue(element1 == intern1, "intern failed"); // must be same object
|
||||
assertTrue(intern2 != null, "intern failed");
|
||||
assertTrue(element3 == intern3, "intern failed");
|
||||
|
||||
Long value1 = Long.valueOf(BASE_KEY + 999);
|
||||
Long value2 = Long.valueOf(BASE_KEY + 999);
|
||||
String value1 = genKey(999);
|
||||
String value2 = genKey(999);
|
||||
assertTrue(set.add(value1), "key not added");
|
||||
assertTrue(!set.add(value1), "key added after second attempt");
|
||||
assertTrue(!set.add(value2), "key should not have been added");
|
||||
@ -164,18 +181,23 @@ public class ReferencedKeyTest {
|
||||
return booleanSupplier.getAsBoolean();
|
||||
}
|
||||
|
||||
static void populate(Map<Long, String> map) {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
Long key = BASE_KEY + i;
|
||||
String value = String.valueOf((char) ('a' + i));
|
||||
map.put(key, value);
|
||||
static List<String> populate(Map<String, String> map) {
|
||||
var keyRefs = genStrings(0, 26, ReferencedKeyTest::genKey);
|
||||
var valueRefs = genStrings(0, 26, ReferencedKeyTest::genValue);
|
||||
for (int i = 0; i < keyRefs.size(); i++) {
|
||||
map.put(keyRefs.get(i), valueRefs.get(i));
|
||||
}
|
||||
return keyRefs;
|
||||
}
|
||||
|
||||
static void populate(Set<Long> set) {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
Long value = BASE_KEY + i;
|
||||
set.add(value);
|
||||
}
|
||||
static List<String> populate(Set<String> set) {
|
||||
var keyRefs = genStrings(0, 26, ReferencedKeyTest::genKey);
|
||||
set.addAll(keyRefs);
|
||||
return keyRefs;
|
||||
}
|
||||
|
||||
// Generate a List of consecutive strings using a function int -> String
|
||||
static List<String> genStrings(int min, int maxExclusive, Function<Integer, String> genString) {
|
||||
return IntStream.range(min, maxExclusive).mapToObj(i -> genString.apply(i)).toList();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user