Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Johnson2019-09-05 11:46:22 -0400
committerAndrew Johnson2019-09-05 11:51:36 -0400
commitc29a7417779c1801027c814e7bd9e4813a9ca0f0 (patch)
treebd61b765432905bef2a87a4b1720767a957fcf20
parent11244ade3970e00ed64a7c295b9bb5e6267b2311 (diff)
downloadorg.eclipse.mat-c29a7417779c1801027c814e7bd9e4813a9ca0f0.tar.gz
org.eclipse.mat-c29a7417779c1801027c814e7bd9e4813a9ca0f0.tar.xz
org.eclipse.mat-c29a7417779c1801027c814e7bd9e4813a9ca0f0.zip
547781: UnsupportedOperationException: not a map:
UnsupportedOperationException: not a map: java.util.Collections$UnmodifiableMap Add additional collections, and tests. Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=547781 Change-Id: Id305596f6016a90166a6aeffb39a3ffef11abbe5
-rw-r--r--plugins/org.eclipse.mat.api/plugin.xml3
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/CommonNameResolver.java40
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/FieldSizeArrayMapExtractor.java116
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/KnownCollectionInfo.java38
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/LinkedListCollectionExtractor.java4
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/RegularEnumSetExtractor.java118
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperCollectionExtractor.java22
-rw-r--r--plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperSetFromMapExtractor.java50
-rw-r--r--plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/CreateCollectionDump.java344
-rw-r--r--plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesBase.java69
-rw-r--r--plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesTest2.java29
-rw-r--r--plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.dita37
-rw-r--r--plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.html61
13 files changed, 746 insertions, 185 deletions
diff --git a/plugins/org.eclipse.mat.api/plugin.xml b/plugins/org.eclipse.mat.api/plugin.xml
index da8578e6..6ecf1d74 100644
--- a/plugins/org.eclipse.mat.api/plugin.xml
+++ b/plugins/org.eclipse.mat.api/plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?> <!--
- Copyright (c) 2008, 2018 SAP AG and IBM Corporation.
+ Copyright (c) 2008, 2019 SAP AG and IBM Corporation.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
@@ -113,6 +113,7 @@
<resolver impl="org.eclipse.mat.inspections.CommonNameResolver$ConstructorResolver" />
<resolver impl="org.eclipse.mat.inspections.CommonNameResolver$ClassTypeResolver" />
<resolver impl="org.eclipse.mat.inspections.CommonNameResolver$StackTraceElementResolver" />
+ <resolver impl="org.eclipse.mat.inspections.CommonNameResolver$EnumResolver" />
<!-- eclipse -->
<resolver impl="org.eclipse.mat.inspections.eclipse.EclipseNameResolver$EclipseClassLoaderResolver" />
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/CommonNameResolver.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/CommonNameResolver.java
index 7c6bc046..88559778 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/CommonNameResolver.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/CommonNameResolver.java
@@ -102,7 +102,7 @@ public class CommonNameResolver
public String resolve(IObject heapObject) throws SnapshotException
{
Object value = heapObject.resolveValue("value"); //$NON-NLS-1$
- return value != null ? String.valueOf(value) : null;
+ return value != null ? String.valueOf(value) : null;
}
}
@@ -431,37 +431,47 @@ public class CommonNameResolver
{
public String resolve(IObject obj) throws SnapshotException
{
- IObject cls = (IObject)obj.resolveValue("declaringClass");
- IObject methodName = (IObject)obj.resolveValue("methodName");
+ IObject cls = (IObject)obj.resolveValue("declaringClass"); //$NON-NLS-1$
+ IObject methodName = (IObject)obj.resolveValue("methodName"); //$NON-NLS-1$
if (cls == null || methodName == null)
return null;
- int line = (Integer)obj.resolveValue("lineNumber");
- IObject fn = (IObject)obj.resolveValue("fileName");
+ int line = (Integer)obj.resolveValue("lineNumber"); //$NON-NLS-1$
+ IObject fn = (IObject)obj.resolveValue("fileName"); //$NON-NLS-1$
String ln;
if (line == -2)
- ln = "(Compiled Code)";
+ ln = "(Compiled Code)"; //$NON-NLS-1$
else if (line == -3)
- ln = "(Native Method)";
+ ln = "(Native Method)"; //$NON-NLS-1$
else if (line == -1)
- ln = "";
+ ln = ""; //$NON-NLS-1$
else if (line == 0)
- ln = "";
+ ln = ""; //$NON-NLS-1$
else
ln = Integer.toString(line);
String name;
if (fn == null)
if (line > 0)
- name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() " + ln;
+ name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() " + ln; //$NON-NLS-1$ //$NON-NLS-2$
else
- name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "()";
+ name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "()"; //$NON-NLS-1$//$NON-NLS-2$
else
if (line > 0)
- name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() ("
- + fn.getClassSpecificName() + ":" + ln + ")";
+ name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() (" //$NON-NLS-1$ //$NON-NLS-2$
+ + fn.getClassSpecificName() + ":" + ln + ")"; //$NON-NLS-1$//$NON-NLS-2$
else
- name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() ("
- + fn.getClassSpecificName() + ")";
+ name = cls.getClassSpecificName() + "." + methodName.getClassSpecificName() + "() (" //$NON-NLS-1$ //$NON-NLS-2$
+ + fn.getClassSpecificName() + ")"; //$NON-NLS-1$
return name;
}
}
+
+ @Subject("java.lang.Enum")
+ public static class EnumResolver implements IClassSpecificNameResolver
+ {
+ public String resolve(IObject heapObject) throws SnapshotException
+ {
+ IObject value = (IObject) heapObject.resolveValue("name"); //$NON-NLS-1$
+ return value != null ? ClassSpecificNameResolverRegistry.resolve(value) : null;
+ }
+ }
}
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/FieldSizeArrayMapExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/FieldSizeArrayMapExtractor.java
new file mode 100644
index 00000000..1c2bd55c
--- /dev/null
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/FieldSizeArrayMapExtractor.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mat.internal.collectionextract;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+
+import org.eclipse.mat.SnapshotException;
+import org.eclipse.mat.inspections.collectionextract.IMapExtractor;
+import org.eclipse.mat.snapshot.ISnapshot;
+import org.eclipse.mat.snapshot.model.IObject;
+import org.eclipse.mat.snapshot.model.IObjectArray;
+
+public class FieldSizeArrayMapExtractor extends FieldSizeArrayCollectionExtractor implements IMapExtractor
+{
+ FieldArrayCollectionExtractor keysExtractor;
+ public FieldSizeArrayMapExtractor(String sizeField, String valuesArrayField, String keysCollectionField)
+ {
+ super(sizeField, valuesArrayField);
+ keysExtractor = new FieldArrayCollectionExtractor(keysCollectionField);
+ }
+
+ public boolean hasCollisionRatio()
+ {
+ return true;
+ }
+
+ public Double getCollisionRatio(IObject collection) throws SnapshotException
+ {
+ return 0.0;
+ }
+
+ public Iterator<Entry<IObject, IObject>> extractMapEntries(IObject collection) throws SnapshotException
+ {
+ final IObjectArray valueArray = extractEntries(collection);
+ final IObjectArray keyArray = keysExtractor.extractEntries(collection);
+ final ISnapshot snapshot = collection.getSnapshot();
+ return new Iterator<Entry<IObject, IObject>>() {
+ int ix = 0;
+ public boolean hasNext()
+ {
+ while (ix < valueArray.getLength())
+ {
+ if (valueArray.getReferenceArray(ix, 1)[0] != 0)
+ return true;
+ ++ix;
+ }
+ return false;
+ }
+
+ public Map.Entry<IObject, IObject> next()
+ {
+ if (hasNext())
+ {
+ final int ix2 = ix++;
+ final IObject key, value;
+ long keyaddr = keyArray.getReferenceArray(ix2, 1)[0];
+ try
+ {
+ int keyid = snapshot.mapAddressToId(keyaddr);
+ key = snapshot.getObject(keyid);
+ }
+ catch (SnapshotException e)
+ {
+ NoSuchElementException ise = new NoSuchElementException();
+ ise.initCause(e);
+ throw ise;
+ }
+
+ long valueaddr = valueArray.getReferenceArray(ix2, 1)[0];
+ try
+ {
+ int valueid = snapshot.mapAddressToId(valueaddr);
+ value = snapshot.getObject(valueid);
+ }
+ catch (SnapshotException e)
+ {
+ NoSuchElementException ise = new NoSuchElementException();
+ ise.initCause(e);
+ throw ise;
+ }
+ return new Map.Entry<IObject, IObject>() {
+
+ public IObject getKey()
+ {
+ return key;
+ }
+
+ public IObject getValue()
+ {
+ return value;
+ }
+
+ public IObject setValue(IObject value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+ throw new NoSuchElementException();
+ }
+
+ };
+ }
+}
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/KnownCollectionInfo.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/KnownCollectionInfo.java
index 81aac22c..07e5ec59 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/KnownCollectionInfo.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/KnownCollectionInfo.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2018 SAP AG, IBM Corporation and others
+ * Copyright (c) 2008, 2019 SAP AG, IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -50,7 +50,7 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.concurrent.ConcurrentLinkedBlockingQueue", new LinkedListCollectionExtractor("count.value", "head.next")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.concurrent.LinkedBlockingDeque", new LinkedListCollectionExtractor("count", "first.next")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.concurrent.LinkedBlockingQueue", new LinkedListCollectionExtractor("count.value", "head.next")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- new CollectionExtractionInfo("java.util.concurrent.ArrayBlockingQueue", new IBM6ArrayListCollectionExtractor("takeIndex", "putIndex", "items", "count")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NONO-NLS-4$
+ new CollectionExtractionInfo("java.util.concurrent.ArrayBlockingQueue", new IBM6ArrayListCollectionExtractor("takeIndex", "putIndex", "items", "count")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
// these store the data in an array
new CollectionExtractionInfo("java.util.concurrent.CopyOnWriteArrayList", new FieldArrayCollectionExtractor("array")), // //$NON-NLS-1$ //$NON-NLS-2$
@@ -68,6 +68,8 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.PriorityQueue", JdkVersion.of(IBM15, IBM16), new FieldSizeArrayCollectionExtractor("size", "elements")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.concurrent.DelayQueue", JdkVersion.except(IBM15, IBM16), new FieldSizeArrayCollectionExtractor("q.size", "q.queue")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.concurrent.DelayQueue", JdkVersion.of(IBM15, IBM16), new FieldSizeArrayCollectionExtractor("q.size", "q.elements")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ new CollectionExtractionInfo("java.util.concurrent.PriorityBlockingQueue", new FieldSizeArrayCollectionExtractor("size", "queue")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ new CollectionExtractionInfo("java.util.concurrent.PriorityBlockingDeque", new FieldSizeArrayCollectionExtractor("size", "queue")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// The length of the array is the size
new CollectionExtractionInfo("java.util.Arrays$ArrayList", new FieldSizeArrayCollectionExtractor("a.@length", "a")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -83,14 +85,17 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.IdentityHashMap", IBM16, new IdentityHashMapCollectionExtractor("size", "elementData")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.IdentityHashMap$KeySet", new KeySetCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.IdentityHashMap$Values", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.IdentityHashMap$EntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
// hash maps
new CollectionExtractionInfo("java.util.HashMap", JdkVersion.except(IBM16), new HashMapCollectionExtractor("size", "table", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.util.HashMap", IBM16, new HashMapCollectionExtractor("elementCount", "elementData", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.util.HashMap$KeySet", new KeySetCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.HashMap$Values", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.HashMap$EntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.LinkedHashMap$LinkedKeySet", new KeySetCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.LinkedHashMap$LinkedValues", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.LinkedHashMap$LinkedEntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
// Some Java 5 PHD files don't have superclass info so add
// LinkedHashMap to list
@@ -112,6 +117,7 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("javax.script.SimpleBindings", IBM16, // //$NON-NLS-1$
new HashMapCollectionExtractor(
"map.elementCount", "map.elementData", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ new CollectionExtractionInfo("javax.management.openmbean.TabularDataSupport", new WrapperMapExtractor("dataMap")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.jar.Attributes", JdkVersion.except(IBM16), new HashMapCollectionExtractor("map.size", "map.table", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.util.jar.Attributes", IBM16, // //$NON-NLS-1$
@@ -131,6 +137,7 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new HashMapCollectionExtractor("elementCount", "elementData", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
new CollectionExtractionInfo("java.util.Hashtable$KeySet", new KeySetCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.Hashtable$ValueCollection", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.Hashtable$EntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
// Some Java 5 PHD files don't have superclass info so add
// Properties to list
@@ -142,10 +149,12 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.WeakHashMap", IBM16, new HashMapCollectionExtractor("elementCount", "elementData", "referent", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.util.WeakHashMap$KeySet", new KeySetCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.WeakHashMap$Values", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.WeakHashMap$EntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("sun.awt.WeakIdentityHashMap", new HashMapCollectionExtractor("map.size", "map.table", "key.referent", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.lang.ThreadLocal$ThreadLocalMap", // //$NON-NLS-1$
new HashMapCollectionExtractor("size", "table", "referent", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ new CollectionExtractionInfo("java.lang.ProcessEnvironment$CheckedEntrySet", new WrapperMapExtractor("s")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$Segment", new HashMapCollectionExtractor("count", "table", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
@@ -153,15 +162,17 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
// small maps.
new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap", JdkVersion.of(JAVA18, IBM18, JAVA19, IBM19), new HashMapCollectionExtractor("baseCount", "table", "key", "val")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap", JdkVersion.except(JAVA18, IBM18, JAVA19, IBM19), new ConcurrentHashMapCollectionExtractor("segments", "key", "value")), // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$KeySetView", new KeySetCollectionExtractor("map")),
- new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$ValuesView", new ValuesCollectionExtractor("map")),
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$KeySetView", new KeySetCollectionExtractor("map")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$ValuesView", new ValuesCollectionExtractor("map")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentHashMap$EntrySetView", new WrapperMapExtractor("map")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListSet", //$NON-NLS-1$
- new ConcurrentSkipListSetCollectionExtractor("m.head.node", "key", "value")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ new KeySetCollectionExtractor("m")), //$NON-NLS-1$
new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap", //$NON-NLS-1$
new ConcurrentSkipListCollectionExtractor("head.node", "key", "value")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap$KeySet", new KeySetCollectionExtractor("map")),
- new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap$Values", new ValuesCollectionExtractor("map")),
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap$KeySet", new KeySetCollectionExtractor("m")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap$Values", new ValuesCollectionExtractor("m")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.concurrent.ConcurrentSkipListMap$EntrySet", new WrapperMapExtractor("m")), //$NON-NLS-1$ //$NON-NLS-2$
// tree maps
new CollectionExtractionInfo("java.util.TreeMap", JdkVersion.except(IBM16), new TreeMapCollectionExtractor("size", "key", "value")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
@@ -170,6 +181,7 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.TreeSet", IBM16, new TreeSetCollectionExtractor("backingMap.size", "keys[]", "values[]")), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
new CollectionExtractionInfo("java.util.TreeMap$KeySet", new KeySetCollectionExtractor("m")), // //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.TreeMap$Values", new ValuesCollectionExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.TreeMap$EntrySet", new WrapperMapExtractor("this$0")), // //$NON-NLS-1$ //$NON-NLS-2$
// wrappers
// also works for SynchronizedSet, SynchronizedSortedSet,
@@ -191,10 +203,12 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.Collections$CheckedCollection", new WrapperCollectionExtractor("c")), //$NON-NLS-1$ //$NON-NLS-2$
// also works for CheckedSortedMap
new CollectionExtractionInfo("java.util.Collections$CheckedMap", new WrapperMapExtractor("m")), //$NON-NLS-1$ //$NON-NLS-2$
- new CollectionExtractionInfo("java.util.Collections$CheckedMap$CheckedEntrySet", new WrapperCollectionExtractor("s")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.Collections$CheckedMap$CheckedEntrySet", new WrapperMapExtractor("s")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.Collections$SetFromMap", new KeySetCollectionExtractor("m")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap", new WrapperMapExtractor("map")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap$KeySet", new KeySetCollectionExtractor("this$0")), //$NON-NLS-1$ //$NON-NLS-2$
- new CollectionExtractionInfo("org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap$Values", new ValuesCollectionExtractor("this$0")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap$Values", new ValuesCollectionExtractor("this$0")), //$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap$EntrySet", new WrapperMapExtractor("this$0")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.awt.RenderingHints", new WrapperMapExtractor("hintmap")), //$NON-NLS-1$ //$NON-NLS-2$
// singletons
@@ -203,6 +217,12 @@ public class KnownCollectionInfo implements ICollectionExtractorProvider
new CollectionExtractionInfo("java.util.Collections$SingletonMap", new SingletonMapExtractor("k", "v")),//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new CollectionExtractionInfo("java.util.Collections$CopiesList", new ReplicatedValueCollectionExtractor("n", "element")),//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ // Enum maps/sets
+ new CollectionExtractionInfo("java.util.EnumMap", new FieldSizeArrayMapExtractor("size", "vals", "keyUniverse")),//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ new CollectionExtractionInfo("java.util.EnumMap$Values", new ValuesCollectionExtractor("this$0")),//$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.EnumMap$KeySet", new KeySetCollectionExtractor("this$0")),//$NON-NLS-1$ //$NON-NLS-2$
+ new CollectionExtractionInfo("java.util.RegularEnumSet", new RegularEnumSetExtractor("elements", "Universe")),//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
// New Java 9 collections
new CollectionExtractionInfo("java.util.ImmutableCollections$Set1", new SingletonCollectionExtractor("e0")), //$NON-NLS-1$ //$NON-NLS-2$
new CollectionExtractionInfo("java.util.ImmutableCollections$List1", new SingletonCollectionExtractor("e0")), //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/LinkedListCollectionExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/LinkedListCollectionExtractor.java
index a4c2f785..f3e2592a 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/LinkedListCollectionExtractor.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/LinkedListCollectionExtractor.java
@@ -62,7 +62,7 @@ public class LinkedListCollectionExtractor extends FieldSizedCollectionExtractor
header = ExtractionUtils.followOnlyOutgoingReferencesExceptLast(leadField, list);
}
if (header == null)
- return null;
+ return new int[0];
IObject previous = header;
IObject current = header;
@@ -177,7 +177,7 @@ public class LinkedListCollectionExtractor extends FieldSizedCollectionExtractor
int entries[] = extractEntryIds(coll);
if (entries == null)
return 0;
- else
+ else
return entries.length;
}
}
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/RegularEnumSetExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/RegularEnumSetExtractor.java
new file mode 100644
index 00000000..77203aa1
--- /dev/null
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/RegularEnumSetExtractor.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mat.internal.collectionextract;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.eclipse.mat.SnapshotException;
+import org.eclipse.mat.collect.ArrayInt;
+import org.eclipse.mat.inspections.collectionextract.IMapExtractor;
+import org.eclipse.mat.snapshot.ISnapshot;
+import org.eclipse.mat.snapshot.model.IObject;
+
+public class RegularEnumSetExtractor extends FieldSizeArrayCollectionExtractor implements IMapExtractor
+{
+
+ /**
+ * For java.util.RegularEnumSet
+ * @param sizeField - holds the bits indicating which set items are used
+ * @param arrayField - all the enum values
+ */
+ public RegularEnumSetExtractor(String sizeField, String arrayField)
+ {
+ super(sizeField, arrayField);
+ }
+
+ public Integer getSize(IObject coll) throws SnapshotException
+ {
+ Object o = coll.resolveValue(sizeField);
+ if (o instanceof Number)
+ {
+ return Long.bitCount(((Number)o).longValue());
+ }
+ return null;
+ }
+
+ public int[] extractEntryIds(IObject coll) throws SnapshotException
+ {
+ Object o = coll.resolveValue(sizeField);
+ long used = 0;
+ if (o instanceof Number)
+ {
+ used = ((Number)o).longValue();
+ }
+
+ ArrayInt arr = new ArrayInt();
+ long referenceArray[] = extractEntries(coll).getReferenceArray();
+ ISnapshot snapshot = coll.getSnapshot();
+ for (int i = 0; i < referenceArray.length && used != 0; i++)
+ {
+ if (referenceArray[i] != 0 && (used & 1) != 0)
+ arr.add(snapshot.mapAddressToId(referenceArray[i]));
+ }
+ return arr.toArray();
+ }
+
+ public boolean hasCollisionRatio()
+ {
+ return true;
+ }
+
+ public Double getCollisionRatio(IObject collection) throws SnapshotException
+ {
+ return 0.0;
+ }
+
+ public Iterator<Entry<IObject, IObject>> extractMapEntries(IObject collection) throws SnapshotException
+ {
+ final ISnapshot snapshot = collection.getSnapshot();
+ final int[] ids = extractEntryIds(collection);
+ return new Iterator<Entry<IObject, IObject>>() {
+ int ix = 0;
+ public boolean hasNext()
+ {
+ return ix < ids.length;
+ }
+
+ public Entry<IObject, IObject> next()
+ {
+ final IObject o;
+ try
+ {
+ o = snapshot.getObject(ids[ix++]);
+ }
+ catch (SnapshotException e)
+ {
+ throw new RuntimeException(e);
+ }
+ return new Entry<IObject, IObject>() {
+
+ public IObject getKey()
+ {
+ return o;
+ }
+
+ public IObject getValue()
+ {
+ return o;
+ }
+
+ public IObject setValue(IObject value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+ };
+ }
+}
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperCollectionExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperCollectionExtractor.java
index 57dae617..fc8fc5f6 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperCollectionExtractor.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperCollectionExtractor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2018 SAP AG, IBM Corporation and others
+ * Copyright (c) 2008, 2019 SAP AG, IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -99,13 +99,29 @@ public class WrapperCollectionExtractor implements ICollectionExtractor
return extractList(coll).getNumberOfNotNullElements();
}
+ private String desc(String msg, IObject coll, AbstractExtractedCollection<?, ?> ec)
+ {
+ if (ec != null)
+ return msg + coll.getDisplayName() + "; " + ec.getDisplayName(); //$NON-NLS-1$
+ try
+ {
+ Object coll2 = coll.resolveValue(field);
+ if (coll2 instanceof IObject)
+ return msg + coll.getDisplayName() + "; " + ((IObject)coll2).getDisplayName(); //$NON-NLS-1$
+ }
+ catch (SnapshotException e)
+ {
+ }
+ return msg + coll.getDisplayName();
+ }
+
protected ExtractedCollection extractList(IObject coll)
{
AbstractExtractedCollection<?, ?> ec = extractCollection(coll);
if (ec instanceof ExtractedCollection)
return (ExtractedCollection) ec;
else
- throw new UnsupportedOperationException("not a list-ish collection: " + coll.getDisplayName() + (ec != null ? ("; " + ec.getDisplayName()) : ""));
+ throw new UnsupportedOperationException(desc("not a list-ish collection: ", coll, ec));
}
protected ExtractedMap extractMap(IObject coll)
@@ -114,7 +130,7 @@ public class WrapperCollectionExtractor implements ICollectionExtractor
if (ec instanceof ExtractedMap)
return (ExtractedMap) ec;
else
- throw new UnsupportedOperationException("not a map: " + coll.getDisplayName() + (ec != null ? ("; " + ec.getDisplayName()) : ""));
+ throw new UnsupportedOperationException(desc("not a map: ", coll, ec));
}
protected AbstractExtractedCollection<?, ?> extractCollection(IObject coll)
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperSetFromMapExtractor.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperSetFromMapExtractor.java
new file mode 100644
index 00000000..e7a865a2
--- /dev/null
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/collectionextract/WrapperSetFromMapExtractor.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mat.internal.collectionextract;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.eclipse.mat.SnapshotException;
+import org.eclipse.mat.inspections.collectionextract.IMapExtractor;
+import org.eclipse.mat.snapshot.model.IObject;
+
+/**
+ * Creates an extractor to view a map as a set.
+ * Just treating it as a map does not work as extractEntryIds needs to return the keys,
+ * not the nodes of type Map.Entry.
+ *
+ */
+public class WrapperSetFromMapExtractor extends WrapperCollectionExtractor implements IMapExtractor
+{
+ WrapperMapExtractor mapext;
+ public WrapperSetFromMapExtractor(String setField, String mapField)
+ {
+ super(setField);
+ mapext = new WrapperMapExtractor(mapField);
+ }
+
+ public boolean hasCollisionRatio()
+ {
+ return mapext.hasCollisionRatio();
+ }
+
+ public Double getCollisionRatio(IObject collection) throws SnapshotException
+ {
+ return mapext.getCollisionRatio(collection);
+ }
+
+ public Iterator<Entry<IObject, IObject>> extractMapEntries(IObject collection) throws SnapshotException
+ {
+ return mapext.extractMapEntries(collection);
+ }
+
+}
diff --git a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/CreateCollectionDump.java b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/CreateCollectionDump.java
index de515009..885bcdec 100644
--- a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/CreateCollectionDump.java
+++ b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/CreateCollectionDump.java
@@ -11,17 +11,18 @@
*******************************************************************************/
package org.eclipse.mat.tests;
-import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.time.Month;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -34,8 +35,14 @@ import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
import java.util.jar.Attributes;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularType;
import javax.print.attribute.standard.JobStateReason;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.Severity;
@@ -68,12 +75,14 @@ public class CreateCollectionDump
{
// Extend the collections
List<Collection>l0 = new ArrayList<Collection>();
+ List<Map>l1 = new ArrayList<Map>();
for (Map m : mapTestData.maps)
{
Collection c = m.values();
if (c.size() == mapTestData.COUNT && c.iterator().next() instanceof String)
{
l0.add(c);
+ //System.out.println("Added " + c.getClass());
}
}
listCollectionTestData2 = new ListCollectionTestData(l0);
@@ -82,36 +91,79 @@ public class CreateCollectionDump
for (Map m : mapTestData.maps)
{
Set s = m.keySet();
+ Set s2 = m.entrySet();
if (s.size() == mapTestData.COUNT && s.iterator().next() instanceof String)
{
l0.add(s);
- //l0.add(m.entrySet());
+ //System.out.println("Added " + s.getClass());
+ // Only add the entry set classes so we can detect them at test time
+ if (s2.getClass().getName().contains("EntrySet"))
+ {
+ l0.add(s2);
+ //System.out.println("Added " + s2.getClass());
+ }
+ else
+ {
+ boolean found = false;
+ for (Collection c : nonListCollectionTestData.collections)
+ {
+ if (c.getClass().equals(s2.getClass()))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ System.out.println("Missing entry set class " + s2.getClass());
+ }
}
}
nonListCollectionTestData2 = new NonListCollectionTestData(l0);
-
+
l0.clear();
for (Map m : emptyMapTestData.maps)
{
Collection c = m.values();
- if (c.size() == mapTestData.COUNT)
+ if (c.size() == 0)
{
l0.add(c);
+ //System.out.println("Added " + c.getClass());
}
}
emptyListCollectionTestData2 = new EmptyListCollectionTestData(l0);
-
+
l0.clear();
for (Map m : emptyMapTestData.maps)
{
Set s = m.keySet();
- if (s.size() == mapTestData.COUNT)
+ Set s2 = m.entrySet();
+ if (s.size() == 0)
{
l0.add(s);
- //l0.add(m.entrySet());
+ //System.out.println("Added " + s.getClass());
+ if (s2.getClass().getName().contains("EntrySet"))
+ {
+ l0.add(s2);
+ //System.out.println("Added " + s.getClass());
+ }
+ else
+ {
+ boolean found = false;
+ for (Collection c : emptyNonListCollectionTestData.collections)
+ {
+ if (c.getClass().equals(s2.getClass()))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ System.out.println("Missing entry set class " + s2.getClass());
+ }
}
}
emptyNonListCollectionTestData2 = new EmptyNonListCollectionTestData(l0);
+
}
public static void main(String[] args) throws Exception
@@ -199,7 +251,9 @@ public class CreateCollectionDump
List<Collection>cols = new ArrayList<Collection>();
/*
* List of classes under test.
- * Space separate class from static method
+ * Space separated class from static method
+ * 1 entry means use constructor
+ * 2 entries means use static method from class
*/
String ls[] = new String[] {
"java.util.AbstractCollection",
@@ -230,6 +284,9 @@ public class CreateCollectionDump
"java.util.Collections emptySet",
"java.util.Collections emptySortedSet",
"java.util.Collections emptyNavigableSet",
+ "java.util.Collections list",
+ "java.util.Collections nCopies",
+ "java.util.Collections newSetFromMap",
"java.util.Collections singleton",
"java.util.Collections singletonList",
"java.util.Collections synchronizedCollection",
@@ -243,6 +300,8 @@ public class CreateCollectionDump
"java.util.Collections unmodifiableSortedSet",
"java.util.Collections unmodifiableNavigableSet",
"java.util.EnumSet",
+ "java.util.EnumSet noneOf",
+ //"java.util.EnumSet allOf",
"java.util.HashSet",
"javax.print.attribute.standard.JobStateReasons",
"java.util.concurrent.LinkedBlockingDeque",
@@ -250,6 +309,7 @@ public class CreateCollectionDump
"java.util.LinkedHashSet",
"java.util.LinkedList",
"java.util.concurrent.LinkedTransferQueue",
+ "java.util.concurrent.PriorityBlockingQueue",
"java.util.PriorityQueue",
"javax.management.relation.RoleList",
"javax.management.relation.RoleUnresolvedList",
@@ -262,6 +322,7 @@ public class CreateCollectionDump
values = new String[COUNT];
for (String cn : ls)
{
+ // Class for constructor
Class<? extends Collection> c = null;
// Methods?
String cn0 = cn;
@@ -304,42 +365,16 @@ public class CreateCollectionDump
}
}
- // To use an existing collection constructor
fillValues(cn);
- List<String>arrayVals = new ArrayList<String>();
- for (int i = 1; i <= COUNT; ++i)
- {
- arrayVals.add(values[i]);
- }
- // And a plain 0-based array
- String values0[] = arrayVals.toArray(new String[arrayVals.size()]);
- Set<String>setVals = new TreeSet<String>(arrayVals);
- Set<String>setVals2 = new HashSet<String>(arrayVals);
- Queue queue = new ArrayDeque(setVals);
- Object[][] args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
- { arrayVals }, { arrayVals }, { setVals2 }, { setVals2 }, { setVals }, { setVals }, { setVals }, { setVals },
- { values0 }, {queue}, {queue},
- { arrayVals, String.class}, { arrayVals, String.class}, { setVals, String.class}, { queue, String.class},
- { setVals, String.class}, { setVals, String.class},
- { values[1] },
- { Collections.emptySet() },
- { Collections.emptySet() },
- };
-
- // Matches argument objects
- Class[][] cons = new Class[][] { {}, { Integer.TYPE }, { Integer.TYPE }, { Integer.TYPE },
- { Collection.class }, { List.class }, { Collection.class }, { Set.class }, { Collection.class }, { Set.class }, { SortedSet.class }, { NavigableSet.class },
- { Object[].class }, { Collection.class }, { Deque.class },
- { Collection.class, Class.class }, { List.class, Class.class }, { Set.class, Class.class }, { Queue.class, Class.class },
- { SortedSet.class, Class.class }, { NavigableSet.class, Class.class },
- { Object.class },
- { Set.class },
- { Collections.class },
- };
+ // To use an existing collection constructor
+ Class[][] cons = buildArgTypes();
int added = 0;
- // Try the different constuctors / methods
+ // Try the different constructors / methods
for (int j = 0; j < cons.length; ++j)
{
+ List<String>arrayVals = new ArrayList<String>();
+ List<Delayed>delayedVals = new ArrayList<Delayed>();
+ Object[][] args = buildArgs(arrayVals, delayedVals);
Collection cl;
try
{
@@ -371,24 +406,8 @@ public class CreateCollectionDump
// To use an existing collection constructor
fillValues(cn);
arrayVals = new ArrayList<String>();
- for (int i = 1; i <= COUNT; ++i)
- {
- arrayVals.add(values[i]);
- }
- // And a plain 0-based array
- values0 = arrayVals.toArray(new String[arrayVals.size()]);
- setVals = new TreeSet<String>(arrayVals);
- setVals2 = new HashSet<String>(arrayVals);
- queue = new ArrayDeque(setVals);
- args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
- { arrayVals }, { arrayVals }, { setVals2 }, { setVals2 }, { setVals }, { setVals }, { setVals }, { setVals },
- { values0 }, {queue}, {queue},
- { arrayVals, String.class}, { arrayVals, String.class}, { setVals, String.class}, { queue, String.class},
- { setVals, String.class}, { setVals, String.class},
- { values[1] },
- { Collections.emptySet() },
- { Collections.emptySet() },
- };
+ delayedVals = new ArrayList<Delayed>();
+ args = buildArgs(arrayVals, delayedVals);
cl = (Collection)method.invoke(null, args[j]);
}
}
@@ -404,12 +423,14 @@ public class CreateCollectionDump
cl.add(values[i]);
}
}
- // Remove and refill
+ List vals = new ArrayList(cl.contains(delayedVals.get(0)) ? delayedVals : arrayVals);
+ // Remove and refill
int from = 0;
int to = COUNT * 2 / 3;
for (int i = to; i <= COUNT; i += 1)
{
- cl.remove(values[i]);
+ //System.out.println(cl.getClass()+" "+arrayVals.size()+" "+delayedVals.size()+" "+delayedVals2.size());
+ cl.remove(vals.get(i - 1));
}
if (cl instanceof List)
{
@@ -421,12 +442,12 @@ public class CreateCollectionDump
}
for (i += 3; i < to; i += 3)
{
- l.add(i - 1, values[i]);
+ l.add(i - 1, vals.get(i - 1));
}
}
for (int i = to; i <= COUNT; i += 1)
{
- cl.add(values[i]);
+ cl.add(vals.get(i - 1));
}
}
catch (UnsupportedOperationException e)
@@ -460,11 +481,22 @@ public class CreateCollectionDump
}
}
}
+ else
+ {
+ // Try to make an empty collection
+ try
+ {
+ cl.clear();
+ }
+ catch (UnsupportedOperationException e)
+ {
+ }
+ }
if (cl.isEmpty() == useEmpty())
{
cols.add(cl);
++added;
- //System.out.println("coll "+cl.size()+" "+cl.getClass()+" "+useEmpty());
+ //System.out.println("coll "+cl.size()+" "+cl.getClass()+" "+useEmpty()+" "+cl);
}
}
catch (NoSuchMethodException e)
@@ -500,6 +532,67 @@ public class CreateCollectionDump
collections = cols.toArray(new Collection[cols.size()]);
}
+ private Object[][] buildArgs(List<String> arrayVals, List<Delayed> delayedVals)
+ {
+ for (int i = 1; i <= COUNT; ++i)
+ {
+ arrayVals.add(values[i]);
+ final int fi = i;
+ delayedVals.add(new Delayed() {
+ public int compareTo(Delayed o)
+ {
+ return 0;
+ }
+ public long getDelay(TimeUnit unit)
+ {
+ return fi;
+ }
+ });
+ }
+ Map<String,Boolean>mapVals = new TreeMap<String,Boolean>();
+ // And a plain 0-indexed array
+ String values0[] = arrayVals.toArray(new String[arrayVals.size()]);
+ Set<String>setVals = new TreeSet<String>(arrayVals);
+ Set<String>setVals2 = new HashSet<String>(arrayVals);
+ Queue queue = new ArrayDeque(setVals);
+ Enumeration<String> enumer = Collections.enumeration(arrayVals);
+ Object[][] args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
+ { arrayVals }, { arrayVals }, { setVals2 }, { setVals2 }, { setVals }, { setVals }, { setVals }, { setVals },
+ { values0 }, {queue}, {queue},
+ { arrayVals, String.class}, { arrayVals, String.class}, { setVals, String.class}, { queue, String.class},
+ { setVals, String.class}, { setVals, String.class},
+ { values[1] },
+ { Collections.emptySet() },
+ { Collections.emptySet() },
+ { enumer },
+ { new Integer(COUNT), values[1] },
+ { mapVals },
+ //{ delayedVals },
+ { Month.class },
+ };
+ return args;
+ }
+
+ private Class[][] buildArgTypes()
+ {
+ // Matches argument objects
+ Class[][] cons = new Class[][] { {}, { Integer.TYPE }, { Integer.TYPE }, { Integer.TYPE },
+ { Collection.class }, { List.class }, { Collection.class }, { Set.class }, { Collection.class }, { Set.class }, { SortedSet.class }, { NavigableSet.class },
+ { Object[].class }, { Collection.class }, { Deque.class },
+ { Collection.class, Class.class }, { List.class, Class.class }, { Set.class, Class.class }, { Queue.class, Class.class },
+ { SortedSet.class, Class.class }, { NavigableSet.class, Class.class },
+ { Object.class },
+ { Set.class },
+ { Collections.class },
+ { Enumeration.class },
+ { Integer.TYPE, Object.class },
+ { Map.class },
+ //{ Collection.class },
+ { Class.class },
+ };
+ return cons;
+ }
+
public void extend(List<Collection>ext)
{
List<Collection>l0 = Arrays.asList(collections);
@@ -649,10 +742,19 @@ public class CreateCollectionDump
}
}
+ public MapTestData(Collection<Map> newmaps)
+ {
+ maps = newmaps.toArray(new Map[newmaps.size()]);
+ }
+
public MapTestData()
{
List<Map>ms = new ArrayList<Map>();
- // List of maps under test
+ /*
+ * List of maps under test
+ * 1 entry means use constructor
+ * 2 entries means use static method from class
+ */
String ls[] = new String[] {
"java.util.AbstractMap",
"java.util.jar.Attributes",
@@ -691,11 +793,14 @@ public class CreateCollectionDump
keys = new String[COUNT];
for (String cn : ls)
{
+ // Class for constructor
Class<? extends Map> c = null;
String cn0 = cn;
// Methods?
String ss[] = cn.split(" ", 2);
+ // Method name
final String mn;
+ // Class for method name
Class<?>cm;
if (ss.length > 1)
{
@@ -729,31 +834,17 @@ public class CreateCollectionDump
continue;
}
}
- // To use an existing map constructor
- fillValues(cn);
- Map<String,String>mapVals = new TreeMap<String,String>();
- for (int i = 1; i <= COUNT; ++i)
- {
- mapVals.put(keys[i], values[i]);
- }
- Map<String,String>mapVals2 = new HashMap<String,String>(mapVals);
- Object[][] args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
- { mapVals2 } , { mapVals } , { mapVals } , { mapVals },
- { mapVals, String.class, String.class }, { mapVals, String.class, String.class }, { mapVals, String.class, String.class },
- { keys[1], values[1] },
- { Collections.emptyMap() },
- };
-
- Class[][] cons = new Class[][] { {}, { Integer.TYPE }, { Integer.TYPE }, { Integer.TYPE },
- { Map.class }, { Map.class }, { SortedMap.class }, { NavigableMap.class },
- { Map.class, Class.class, Class.class }, { SortedMap.class, Class.class, Class.class }, { NavigableMap.class, Class.class, Class.class },
- { Object.class, Object.class },
- { Map.class },
- };
+ fillValues(cn);
+ // Argument types
+ Class[][] cons = buildArgTypes();
int added = 0;
for (int j = 0; j < cons.length; ++j)
{
+ // To use an existing map constructor
+ Map<Enum,String>enumVals = new TreeMap<Enum,String>();
+ Map<String,String>mapVals = new TreeMap<String,String>();
+ Object[][] args = buildArgs(mapVals, enumVals);
Map cl;
try
{
@@ -771,25 +862,16 @@ public class CreateCollectionDump
}
else
{
- cl = (Map)cm.getMethod(mn, cons[j]).invoke(null, args[j]);
+ Method method = cm.getMethod(mn, cons[j]);
+ cl = (Map)method.invoke(null, args[j]);
c = cl.getClass();
if (!c.getName().equals(cn))
{
+ // Class name changed, so rebuild initial values
cn = c.getName();
fillValues(cn);
- mapVals = new TreeMap<String,String>();
- for (int i = 1; i <= COUNT; ++i)
- {
- mapVals.put(keys[i], values[i]);
- }
- mapVals2 = new HashMap<String,String>(mapVals);
- args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
- { mapVals2 } , { mapVals } , { mapVals } , { mapVals },
- { mapVals, String.class, String.class }, { mapVals, String.class, String.class }, { mapVals, String.class, String.class },
- { keys[1], values[1] },
- { Collections.emptyMap() },
- };
- cl = (Map)cm.getMethod(mn, cons[j]).invoke(null, args[j]);
+ args = buildArgs(mapVals, enumVals);
+ cl = (Map)method.invoke(null, args[j]);
c = cl.getClass();
}
}
@@ -863,11 +945,22 @@ public class CreateCollectionDump
}
}
}
+ else
+ {
+ // Try to make an empty map
+ try
+ {
+ cl.clear();
+ }
+ catch (UnsupportedOperationException e)
+ {
+ }
+ }
if (cl.isEmpty() == useEmpty())
{
ms.add(cl);
++added;
- //System.out.println("map "+cl.size()+" "+cl.getClass()+" "+useEmpty()+" "+mn+" "+j);
+ //System.out.println("map "+cl.size()+" "+cl.getClass()+" "+useEmpty()+" "+mn+" "+j+" "+cl);
}
}
catch (InstantiationException e)
@@ -897,6 +990,57 @@ public class CreateCollectionDump
maps = ms.toArray(new Map[ms.size()]);
}
+ private Object[][] buildArgs(Map<String, String> mapVals, Map<Enum, String> enumVals)
+ {
+ for (int i = 1; i <= COUNT; ++i)
+ {
+ mapVals.put(keys[i], values[i]);
+ if (i <= 12)
+ enumVals.put(Month.of(i), values[i]);
+ }
+ SimpleType<String> st[] = Collections.nCopies(COUNT, SimpleType.STRING).toArray(new SimpleType[COUNT]);
+ CompositeType ct1;
+ TabularType tt1;
+ try
+ {
+ // keys[], values[] is 1-offset, we need 0-offset
+ ct1 = new CompositeType("composite test", "a composite type", mapVals.keySet().toArray(new String[COUNT]), mapVals.values().toArray(new String[COUNT]), st);
+ tt1 = new TabularType("tabular test", "testing tabular types with strings", ct1, mapVals.keySet().toArray(new String[COUNT]));
+ }
+ catch (OpenDataException e)
+ {
+ e.printStackTrace();
+ ct1 = null;
+ tt1 = null;
+ }
+ Map<String,String>mapVals2 = new HashMap<String,String>(mapVals);
+ // Arguments
+ Object[][] args = new Object[][] { {}, { Integer.valueOf(0) }, { new Integer(COUNT) }, { new Integer(COUNT * 2) },
+ { mapVals2 } , { mapVals } , { mapVals } , { mapVals },
+ { mapVals, String.class, String.class }, { mapVals, String.class, String.class }, { mapVals, String.class, String.class },
+ { keys[1], values[1] },
+ { Collections.emptyMap() },
+ //{ Month.class },
+ //{ enumVals },
+ //{ tt1 },
+ };
+ return args;
+ }
+
+ private Class[][] buildArgTypes()
+ {
+ Class[][] cons = new Class[][] { {}, { Integer.TYPE }, { Integer.TYPE }, { Integer.TYPE },
+ { Map.class }, { Map.class }, { SortedMap.class }, { NavigableMap.class },
+ { Map.class, Class.class, Class.class }, { SortedMap.class, Class.class, Class.class }, { NavigableMap.class, Class.class, Class.class },
+ { Object.class, Object.class },
+ { Map.class },
+ //{ Class.class },
+ //{ Map.class },
+ //{ TabularType.class },
+ };
+ return cons;
+ }
+
public String toString()
{
return Arrays.toString(maps);
diff --git a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesBase.java b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesBase.java
index f18f8016..9c5376d9 100644
--- a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesBase.java
+++ b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesBase.java
@@ -13,6 +13,7 @@ package org.eclipse.mat.tests.collect;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.isOneOf;
+import static org.hamcrest.core.AnyOf.anyOf;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.StringContains.containsString;
import static org.hamcrest.core.StringStartsWith.startsWith;
@@ -21,6 +22,7 @@ import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo;
import static org.hamcrest.number.OrderingComparison.lessThanOrEqualTo;
import java.io.Serializable;
+import java.util.regex.Pattern;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.query.IContextObject;
@@ -33,11 +35,38 @@ import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.snapshot.query.SnapshotQuery;
import org.eclipse.mat.util.MessageUtil;
import org.eclipse.mat.util.VoidProgressListener;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.rules.ErrorCollector;
public class ExtractCollectionEntriesBase
{
+ /**
+ * Hamcrest style matcher for regular expression matching.
+ * Hamcrest 1.1 doesn't have this.
+ * @param regex
+ * @return true if the string matches the pattern
+ */
+ public static Matcher<java.lang.String> matchesPattern(final java.lang.String regex)
+ {
+ return new TypeSafeMatcher<String>() {
+ Pattern pat = Pattern.compile(regex);
+
+ public void describeTo(Description description)
+ {
+ description.appendText("a string matching '" + regex + "'");
+ }
+
+ @Override
+ protected boolean matchesSafely(String item)
+ {
+ return pat.matcher(item).matches();
+ }
+
+ };
+ }
@Rule
public ErrorCollector collector = new ErrorCollector();
@@ -74,8 +103,8 @@ public class ExtractCollectionEntriesBase
{
collector.checkThat(prefix + "List entry should start with the type", cv, startsWith(name));
}
- collector.checkThat(prefix + "Should end with number or aAbB: " + cv,
- cv.matches(".*([0-9]+|[aAbB]+)$"), equalTo(true));
+ collector.checkThat(prefix + "Should end with number or aAbB", cv,
+ matchesPattern(".*([0-9]+|[aAbB]+)$"));
}
else
{
@@ -130,8 +159,8 @@ public class ExtractCollectionEntriesBase
{
collector.checkThat(prefix + "Hash set entry should start with the type", cv, startsWith(name));
}
- collector.checkThat(prefix + "Should end with number or aAbB: " + cv,
- cv.matches(".*([0-9]+|[aAbB]+)$"), equalTo(true));
+ collector.checkThat(prefix + "Should end with number or aAbB", cv,
+ matchesPattern(".*([0-9]+|[aAbB]+)$"));
}
else
{
@@ -149,19 +178,24 @@ public class ExtractCollectionEntriesBase
protected void checkCollection(long objAddress, int numEntries, ISnapshot snapshot) throws SnapshotException
{
checkMap(objAddress, numEntries, snapshot);
- checkHashEntries(objAddress, numEntries, snapshot, false);
+ checkHashEntries(objAddress, numEntries, snapshot, false, false);
}
/**
* HashMap entries.
- * Check keys
+ * Check keys and values.
+ * Map:
+ * 123 : full.class.name:123
+ * Set from map
+ * full.class.name:123 : <other>
* @param objAddress
* @param numEntries
* @param snapshot
* @param checkValueString
+ * @param isMap whether this is a normal test map, or a map from a set
* @throws SnapshotException
*/
- protected void checkHashEntries(long objAddress, int numEntries, ISnapshot snapshot, boolean checkValueString) throws SnapshotException
+ protected void checkHashEntries(long objAddress, int numEntries, ISnapshot snapshot, boolean checkValueString, boolean isMap) throws SnapshotException
{
IObject obj = snapshot.getObject(snapshot.mapAddressToId(objAddress));
String prefix = obj.getTechnicalName()+": ";
@@ -196,24 +230,29 @@ public class ExtractCollectionEntriesBase
if (k1 != null)
{
collector.checkThat(prefix+"Key should be an String", k1, instanceOf(String.class));
- if (checkValueString && k1 instanceof String)
+ if (isMap && checkValueString && k1 instanceof String)
{
- collector.checkThat(prefix+"Should be a number or aAbB", ((String)k1).matches("[0-9]+|[aAbB]+"), equalTo(true));
+ collector.checkThat(prefix+"Key should be a number or aAbB", (String)k1, matchesPattern("[0-9]+|[aAbB]+"));
}
if (checkValueString && k1 instanceof String)
{
- collector.checkThat(prefix+"Should end with a number or aAbB", ((String)k1).matches(".*([0-9]+|[aAbB]+)$"), equalTo(true));
+ collector.checkThat(prefix+"Key should end with a number or aAbB", (String)k1, matchesPattern(".*([0-9]+|[aAbB]+)$"));
+ }
+ if (!isMap && checkValueString && k1 instanceof String)
+ {
+ // Some of the sets are KeySets from Maps so have numeric/aAbB not class names
+ collector.checkThat(prefix+"Key contains name of collection class or a number or aAbB", (String)k1, anyOf(containsString(obj.getClazz().getName()), matchesPattern("[0-9]+|[aAbB]+")));
}
}
if (v1 != null)
{
collector.checkThat(prefix+"Value should be an String", v1, instanceOf(String.class));
}
- if (checkValueString && k1 instanceof String && v1 instanceof String)
+ if (isMap && checkValueString && k1 instanceof String && v1 instanceof String)
{
collector.checkThat(prefix+"Value contains key", (String)v1, containsString((String)k1));
}
- if (checkValueString && v1 instanceof String)
+ if (isMap && checkValueString && v1 instanceof String)
{
collector.checkThat(prefix+"Value contains name of collection class", (String)v1, containsString(obj.getClazz().getName()));
}
@@ -282,8 +321,10 @@ public class ExtractCollectionEntriesBase
IResultTable table2 = (IResultTable) result2;
int rowCount2 = table2.getRowCount();
String className = snapshot.getClassOf(snapshot.mapAddressToId(objAddress)).getName();
- if (className.equals("java.util.TreeMap") || className.equals("java.util.TreeMap$KeySet") ||
- className.equals("java.util.concurrent.ConcurrentSkipListMap") || className.equals("java.util.concurrent.ConcurrentSkipListMap$KeySet") ||
+ if (className.equals("java.util.TreeMap") || className.equals("java.util.TreeMap$KeySet") ||
+ className.equals("java.util.TreeMap$EntrySet") ||
+ className.equals("java.util.concurrent.ConcurrentSkipListMap") || className.equals("java.util.concurrent.ConcurrentSkipListMap$KeySet") ||
+ className.equals("java.util.concurrent.ConcurrentSkipListMap$EntrySet") ||
className.equals("java.util.TreeSet") || className.equals("java.util.concurrent.ConcurrentSkipListSet"))
{
// TreeMaps and ConcurrentSkipListMap don't appear in the fill ratio report as they
diff --git a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesTest2.java b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesTest2.java
index dd2c363b..41358576 100644
--- a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesTest2.java
+++ b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/collect/ExtractCollectionEntriesTest2.java
@@ -158,6 +158,7 @@ public class ExtractCollectionEntriesTest2 extends ExtractCollectionEntriesBase
checkCollectionSize(objAddress, numEntries, snapshot);
if (!name.startsWith("java.util.concurrent.LinkedBlocking") &&
!name.startsWith("java.util.concurrent.LinkedTransfer") &&
+ !name.startsWith("java.util.concurrent.SynchronousQueue") &&
!name.startsWith("java.util.concurrent.ConcurrentLinked"))
{
checkCollectionFillRatio(objAddress, numEntries, snapshot);
@@ -165,9 +166,12 @@ public class ExtractCollectionEntriesTest2 extends ExtractCollectionEntriesBase
if (!name.contains("Array") && !name.contains("Queue") && !name.contains("Deque")
&& !(name.startsWith("java.util.Collections") && (name.endsWith("Collection") || name.endsWith("SingletonSet"))))
{
- checkHashEntries(objAddress, numEntries, snapshot, false);
+ checkHashEntries(objAddress, numEntries, snapshot, true, false);
checkMapCollisionRatio(objAddress, numEntries, snapshot);
- checkHashSetObjects(objAddress, numEntries, checkVals, snapshot);
+ if (!name.contains("EntrySet"))
+ {
+ checkHashSetObjects(objAddress, numEntries, checkVals, snapshot);
+ }
}
else
{
@@ -239,14 +243,27 @@ public class ExtractCollectionEntriesTest2 extends ExtractCollectionEntriesBase
long objAddress = nr.getObjectAddress();
int numEntries = 0;
checkCollectionSize(objAddress, numEntries, snapshot);
- checkHashEntries(objAddress, numEntries, snapshot, true);
+ checkHashEntries(objAddress, numEntries, snapshot, true, false);
String name = nr.getObject().getClazz().getName();
- if (!name.contains("Array") && !name.contains("Queue") && !name.contains("Deque"))
+ if (!name.startsWith("java.util.concurrent.LinkedBlocking") &&
+ !name.startsWith("java.util.concurrent.LinkedTransfer") &&
+ !name.startsWith("java.util.concurrent.SynchronousQueue") &&
+ !name.startsWith("java.util.concurrent.ConcurrentLinked"))
{
checkCollectionFillRatio(objAddress, numEntries, snapshot);
+ }
+ if (!name.contains("Array") && !name.contains("Queue") && !name.contains("Deque")
+ && !(name.startsWith("java.util.Collections") && (name.endsWith("Collection") || name.endsWith("SingletonSet"))))
+ {
+ checkHashEntries(objAddress, numEntries, snapshot, true, false);
checkMapCollisionRatio(objAddress, numEntries, snapshot);
checkHashSetObjects(objAddress, numEntries, checkVals, snapshot);
}
+ else
+ {
+ // Other queries also work with list_entries
+ checkList(objAddress, numEntries, checkVals, snapshot);
+ }
}
}
}
@@ -301,7 +318,7 @@ public class ExtractCollectionEntriesTest2 extends ExtractCollectionEntriesBase
}
else
{
- checkHashEntries(objAddress, numEntries, snapshot, true);
+ checkHashEntries(objAddress, numEntries, snapshot, true, true);
checkMap(objAddress, numEntries, snapshot);
}
}
@@ -331,7 +348,7 @@ public class ExtractCollectionEntriesTest2 extends ExtractCollectionEntriesBase
++objectsFound;
long objAddress = nr.getObjectAddress();
int numEntries = 0;
- checkHashEntries(objAddress, numEntries, snapshot, true);
+ checkHashEntries(objAddress, numEntries, snapshot, true, true);
checkMap(objAddress, numEntries, snapshot);
}
}
diff --git a/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.dita b/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.dita
index a2d25515..3c453674 100644
--- a/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.dita
+++ b/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.dita
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2008, 2010 SAP AG.
+ Copyright (c) 2008, 2019 SAP AG and IBM Corporation.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
Contributors:
SAP AG - initial API and implementation
+ IBM Corporation - additional collection classes
-->
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd" >
<task id="task_analyzingjavacollectionusage" xml:lang="en-us">
@@ -16,7 +17,7 @@
<copyright>
<copyryear year=""></copyryear>
<copyrholder>
- Copyright (c) 2008, 2010 SAP AG and others.
+ Copyright (c) 2008, 2019 SAP AG, IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
@@ -97,6 +98,9 @@
<codeblock>java.util.Collections$EmptySet</codeblock>
</li>
<li>
+ <codeblock>java.util.Collections$SetFromMap</codeblock>
+ </li>
+ <li>
<codeblock>java.util.Collections$SingletonList</codeblock>
</li>
<li>
@@ -148,6 +152,12 @@
<codeblock>java.util.concurrent.SynchronousQueue</codeblock>
</li>
<li>
+ <codeblock>java.util.EnumMap</codeblock>
+ </li>
+ <li>
+ <codeblock>java.util.EnumSet</codeblock>
+ </li>
+ <li>
<codeblock>java.util.HashMap</codeblock>
</li>
<li>
@@ -157,6 +167,9 @@
<codeblock>java.util.Hashtable</codeblock>
</li>
<li>
+ <codeblock>java.util.IdentityHashMap</codeblock>
+ </li>
+ <li>
<codeblock>java.util.ImmutableCollections$List0</codeblock>
</li>
<li>
@@ -238,6 +251,9 @@
<codeblock>java.util.Collections$EmptySet</codeblock>
</li>
<li>
+ <codeblock>java.util.Collections$SetFromMap</codeblock>
+ </li>
+ <li>
<codeblock>java.util.Collections$SingletonList</codeblock>
</li>
<li>
@@ -304,6 +320,12 @@
<codeblock>java.util.concurrent.SynchronousQueue</codeblock>
</li>
<li>
+ <codeblock>java.util.EnumMap</codeblock>
+ </li>
+ <li>
+ <codeblock>java.util.EnumSet</codeblock>
+ </li>
+ <li>
<codeblock>java.util.HashMap</codeblock>
</li>
<li>
@@ -437,15 +459,9 @@
<codeblock>java.util.concurrent.ConcurrentHashMap$Segment</codeblock>
</li>
<li>
- <codeblock>java.util.HashMap</codeblock>
- </li>
- <li>
<codeblock>java.util.HashSet</codeblock>
</li>
<li>
- <codeblock>java.util.Hashtable</codeblock>
- </li>
- <li>
<codeblock>java.util.concurrent.ConcurrentHashMap</codeblock>
</li>
<li>
@@ -455,13 +471,10 @@
<codeblock>java.util.concurrent.ConcurrentSkipListSet</codeblock>
</li>
<li>
- <codeblock>java.util.Collections$CheckedSet</codeblock>
- </li>
- <li>
<codeblock>java.util.Collections$CheckedMap</codeblock>
</li>
<li>
- <codeblock>java.util.Collections$UnmodifiableMap</codeblock>
+ <codeblock>java.util.Collections$CheckedSet</codeblock>
</li>
<li>
<codeblock>java.util.Collections$SynchronizedMap</codeblock>
diff --git a/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.html b/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.html
index 9b35dc8f..b0895e3d 100644
--- a/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.html
+++ b/plugins/org.eclipse.mat.ui.help/tasks/analyzingjavacollectionusage.html
@@ -6,8 +6,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="DC.Type" content="task"/>
<meta name="DC.Title" content="Analyzing Java Collection Usage"/>
-<meta name="copyright" content="Copyright (c) 2008, 2010 SAP AG and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html " type="primary"/>
-<meta name="DC.Rights.Owner" content="Copyright (c) 2008, 2010 SAP AG and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html " type="primary"/>
+<meta name="copyright" content="Copyright (c) 2008, 2019 SAP AG, IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html " type="primary"/>
+<meta name="DC.Rights.Owner" content="Copyright (c) 2008, 2019 SAP AG, IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html " type="primary"/>
<meta name="DC.Format" content="XHTML"/>
<meta name="DC.Identifier" content="task_analyzingjavacollectionusage"/>
<meta name="DC.Language" content="en-us"/>
@@ -126,6 +126,11 @@
</li>
<li class="li">
+ <pre class="pre codeblock">java.util.Collections$SetFromMap</pre>
+
+ </li>
+
+ <li class="li">
<pre class="pre codeblock">java.util.Collections$SingletonList</pre>
</li>
@@ -211,6 +216,16 @@
</li>
<li class="li">
+ <pre class="pre codeblock">java.util.EnumMap</pre>
+
+ </li>
+
+ <li class="li">
+ <pre class="pre codeblock">java.util.EnumSet</pre>
+
+ </li>
+
+ <li class="li">
<pre class="pre codeblock">java.util.HashMap</pre>
</li>
@@ -226,6 +241,11 @@
</li>
<li class="li">
+ <pre class="pre codeblock">java.util.IdentityHashMap</pre>
+
+ </li>
+
+ <li class="li">
<pre class="pre codeblock">java.util.ImmutableCollections$List0</pre>
</li>
@@ -357,6 +377,11 @@
</li>
<li class="li">
+ <pre class="pre codeblock">java.util.Collections$SetFromMap</pre>
+
+ </li>
+
+ <li class="li">
<pre class="pre codeblock">java.util.Collections$SingletonList</pre>
</li>
@@ -467,6 +492,16 @@
</li>
<li class="li">
+ <pre class="pre codeblock">java.util.EnumMap</pre>
+
+ </li>
+
+ <li class="li">
+ <pre class="pre codeblock">java.util.EnumSet</pre>
+
+ </li>
+
+ <li class="li">
<pre class="pre codeblock">java.util.HashMap</pre>
</li>
@@ -678,26 +713,11 @@
</li>
<li class="li">
- <pre class="pre codeblock">java.util.HashMap</pre>
-
- </li>
-
- <li class="li">
<pre class="pre codeblock">java.util.HashSet</pre>
</li>
<li class="li">
- <pre class="pre codeblock">java.util.Hashtable</pre>
-
- </li>
-
- <li class="li">
- <pre class="pre codeblock">java.util.IdentityHashMap</pre>
-
- </li>
-
- <li class="li">
<pre class="pre codeblock">java.util.concurrent.ConcurrentHashMap</pre>
</li>
@@ -713,17 +733,12 @@
</li>
<li class="li">
- <pre class="pre codeblock">java.util.Collections$CheckedSet</pre>
-
- </li>
-
- <li class="li">
<pre class="pre codeblock">java.util.Collections$CheckedMap</pre>
</li>
<li class="li">
- <pre class="pre codeblock">java.util.Collections$UnmodifiableMap</pre>
+ <pre class="pre codeblock">java.util.Collections$CheckedSet</pre>
</li>

Back to the top