/* * Copyright (c) 2016, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package gc.g1.humongousObjects.objectGraphTest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public final class TestcaseData { /** * Temporary node description used during parsing */ private static class InternalParsedNode { public String id; public final ArrayList<Integer> connectedTo = new ArrayList<>(); public final ArrayList<Integer> connectedFrom = new ArrayList<>(); public final List<ObjectGraph.ReferenceType> referencesTypes = new ArrayList<>(); public boolean isHumongous; } /** * Immutable node description. * Contains: * Node id * Humongous flag * List of external references' types * List of nodes connected to */ public static class FinalParsedNode { public final String id; public final boolean isHumongous; private final List<ObjectGraph.ReferenceType> referencesTypes; private final ArrayList<Integer> connectedTo; public FinalParsedNode(InternalParsedNode internalParsedNode) { referencesTypes = internalParsedNode.referencesTypes; connectedTo = internalParsedNode.connectedTo; id = internalParsedNode.id; isHumongous = internalParsedNode.isHumongous; } public List<ObjectGraph.ReferenceType> getReferencesTypes() { return Collections.unmodifiableList(referencesTypes); } public List<Integer> getConnectedTo() { return Collections.unmodifiableList(connectedTo); } } /** * @param testcaseDesc testcase in the following notation: * H - humongous node * S - non-humongous node * s - external soft reference * w - external weak reference * Hs->Sw - 1st node is humongous, externally soft referenced and strong references to non-humongous node 2 which is * externally weak referenced * H->1 - humongous node connects to the first node of chain * @return list of nodes description in FinalParsedNode structure */ public static List<FinalParsedNode> parse(String testcaseDesc) { String[] nodes = testcaseDesc.split("-"); List<InternalParsedNode> internalParsedNodeList = new ArrayList<>(); for (int i = 0; i < nodes.length; ++i) { String node = nodes[i]; InternalParsedNode nd; if (node.contains("1")) { nd = internalParsedNodeList.get(0); } else { nd = new InternalParsedNode(); internalParsedNodeList.add(nd); nd.id = String.valueOf(i); } if (node.startsWith(">")) { nd.connectedFrom.add(i - 1); } if (node.endsWith("<")) { nd.connectedFrom.add(i + 1); } if (node.contains("w")) { nd.referencesTypes.add(ObjectGraph.ReferenceType.WEAK); } if (node.contains("s")) { nd.referencesTypes.add(ObjectGraph.ReferenceType.SOFT); } if (node.contains("H")) { nd.isHumongous = true; } if (node.contains("S")) { nd.isHumongous = false; } } // we have connectedFrom but we need to get connectedTo for (int i = 0; i < internalParsedNodeList.size(); ++i) { for (Integer reference : internalParsedNodeList.get(i).connectedFrom) { internalParsedNodeList.get(reference).connectedTo.add(i); } } List<FinalParsedNode> finalParsedNodes = internalParsedNodeList.stream().map(FinalParsedNode::new) .collect(Collectors.toList()); return finalParsedNodes; } /** * @return List of pregenerated testing cases */ public static List<String> getPregeneratedTestcases() { return Arrays.asList( "Hw", "Sw", "Sw->Hw", "Hw->Sw", "Sw<->Hw", "Sw<->Sw", "Hw->Sw->Sw", "Hw->Sw->Sw", "Sw->Hw->Sw", "Hw->Sw->Sw->1", "Sw->Hw->Sw->1", "Sw->Hw->Hw->1", "Sw<->Hw<->Hw->1", "Sw<->Hw<->Sw->1", "Sw->Hw<->Sw", "Hs", "Ss", "Ss->Hs", "Hs->Ss", "Ss<->Hs", "Ss<->Ss", "Hs->Ss->Ss", "Hs->Ss->Ss", "Ss->Hs->Ss", "Hs->Ss->Ss->1", "Ss->Hs->Ss->1", "Ss->Hs->Hs->1", "Ss<->Hs<->Hs->1", "Ss<->Hs<->Ss->1", "Ss->Hs<->Ss", "Ss->Hw", "Sw->Hs", "Hs->Sw", "Hw->Ss", "Ss<->Hw", "Sw<->Hs", "Ss<->Sw", "Sw<->Ss", "Hs->Sw->Sw", "Hw->Ss->Sw", "Hw->Sw->Ss", "Ss->Hw->Sw", "Sw->Hs->Sw", "Sw->Hw->Ss", "Hs->Sw->Sw->1", "Hw->Ss->Sw->1", "Hw->Sw->Ss->1", "Ss->Hw->Sw->1", "Ss->Hs->Sw->1", "Sw->Hw->Ss->1", "Ss->Hw->Hw->1", "Sw->Hs->Hw->1", "Sw->Hw->Hs->1", "Ss<->Hw<->Hw->1", "Sw<->Hs<->Hw->1", "Sw<->Hw<->Hs->1", "Ss<->Hw<->Sw->1", "Sw<->Hs<->Sw->1", "Sw<->Hw<->Ss->1", "Ss->Hw<->Sw", "Sw->Hs<->Sw", "Sw->Hw<->Ss" ); } }