Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/gc/NonbranchyTree.java
66661 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.share.gc;2425import nsk.share.test.ExecutionController;26import nsk.share.test.LocalRandom;2728import java.io.PrintStream;2930/**31* <tt>NonbranchyTree</tt> defines a tree structure. Each node of the tree32* always has one son. A node may have the second son with probability33* <tt>branchiness</tt>.34*/35public class NonbranchyTree {3637/** Minimal size of each node (in bytes) */38public final static int MIN_NODE_SIZE = 20;39private final Node root;40private final float branchiness;41private final ExecutionController controller;4243/**44* Creates a new tree with number of nodes not more than45* <tt>numberOfNodes</tt>. The implementation uses recursion to build the46* tree, so if <tt>StackOverflowError</tt> or <tt>OutOfMemoryError</tt> is47* thrown, the recursion is stopped and the method finishes building of the48* tree. Each node consists of <tt>byte[]</tt> of length <tt>size</tt>.49*50* @param numberOfNodes maximum number of nodes for the tree.51* @param branchiness probability for each node to have the second son.52* @param size number of bytes to store in a node.53*54* @throws <i>IllegalArgumentException</i> if <tt>numberOfNodes</tt> is55* less than 1; or <tt>branchiness</tt> is greater than 1, or less56* or equal than 0; or <tt>size</tt> is less than 1.57*58*/59public NonbranchyTree(int numberOfNodes, float branchiness, int size) {60this(numberOfNodes, branchiness, size, null);61}6263public NonbranchyTree(int numberOfNodes, float branchiness, int size, ExecutionController controller) {64if (numberOfNodes < 1) {65throw new IllegalArgumentException("Illegal number of nodes: "66+ numberOfNodes + ", must be at least 1.");67}68if ((branchiness >= 1) || (branchiness <= 0)) {69throw new IllegalArgumentException("Illegal value of branchiness: "70+ branchiness + ", must be greater than 0 and less than 1.");71}72if (size < 1) {73throw new IllegalArgumentException("Illegal size of nodes: "74+ size + ", must be at least 1.");75}76// ensure that LocalRandom is loaded and has enough memory77LocalRandom.nextBoolean();78this.branchiness = branchiness;79this.controller = controller;80this.root = createTree(numberOfNodes, size);81}8283// Create a new tree with specified number of nodes and size of each node84private Node createTree(int numberOfNodes, int size) {85// Make sure we respect the controller and stop test after86// given time.87if (controller != null && !controller.continueExecution()) {88return null;89}9091Node node = new Node(size);92try {93if (numberOfNodes == 0) {94// No more nodes need to be built95return null;96} else if (numberOfNodes == 1) {97return node;98} else if (numberOfNodes == 2) {99node.left = createTree(1, size);100return node;101} else {102// Create a few nodes103if (makeRightNode()) {104// The node will have two sons105int leftNodes = 1 + LocalRandom.nextInt(numberOfNodes - 2);106int rightNodes = numberOfNodes - 1 - leftNodes;107108node.left = createTree(leftNodes, size);109node.right = createTree(rightNodes, size);110} else {111// The node will have just one son112Node leftTree = createTree(numberOfNodes - 1, size);113node.left = leftTree;114}115return node;116} // if117} catch(StackOverflowError e) {118// No more memory for such long tree119return node;120} catch(OutOfMemoryError e) {121// No more memory for such long tree122return node;123} // try124} // createTree()125126// Define the "branchiness" of the tree127private boolean makeRightNode() {128return (LocalRandom.nextFloat() < branchiness);129}130131/**132* Bends the tree. A son of a leaf of the tree is set to the root node.133*134*/135public void bend() {136bend(root);137}138139// Bend the tree: make a reference from a leat of the tree to the specified140// node141private void bend(Node markedNode) {142Node node = root;143144while ( (node.left != null) || (node.right != null) )145node = node.left;146node.right = markedNode;147}148149/**150* Prints the whole tree from the root to the defined PrintStream.151*152* @param out PrintStream to print the tree in153*154*/155public void print(PrintStream out) {156print(out, root);157}158159// Print the sub-tree from the specified node and down160private void print(PrintStream out, Node node) {161node.print(out);162if (node.left != null)163print(out, node.left);164if (node.right != null)165print(out, node.right);166}167}168169// The class defines a node of a tree170class Node {171Node left;172Node right;173byte[] core;174175Node(int size) {176left = null;177right = null;178core = new byte[size];179180// Initizlize the core array181for (int i = 0; i < size; i++)182core[i] = (byte) i;183}184185// Print the node info186void print(PrintStream out) {187out.println("node = " + this + " (" + left + ", " + right + ")");188}189}190191192