Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/gc/NonbranchyTree.java
41161 views
/*1* Copyright (c) 2003, 2020, 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 java.io.*;26import java.util.*;2728import nsk.share.test.ExecutionController;29import nsk.share.test.LocalRandom;3031/**32* <tt>NonbranchyTree</tt> defines a tree structure. Each node of the tree33* always has one son. A node may have the second son with probability34* <tt>branchiness</tt>.35*/36public class NonbranchyTree {3738/** Minimal size of each node (in bytes) */39public final static int MIN_NODE_SIZE = 20;40private Node root;41private int numberOfNodes;42private float branchiness;43private int size;44private ExecutionController controller;4546/**47* Creates a new tree with number of nodes not more than48* <tt>numberOfNodes</tt>. The implementation uses recursion to build the49* tree, so if <tt>StackOverflowError</tt> or <tt>OutOfMemoryError</tt> is50* thrown, the recursion is stopped and the method finishes building of the51* tree. Each node consists of <tt>byte[]</tt> of length <tt>size</tt>.52*53* @param numberOfNodes maximum number of nodes for the tree.54* @param branchiness probability for each node to have the second son.55* @param size number of bytes to store in a node.56*57* @throws <i>IllegalArgumentException</i> if <tt>numberOfNodes</tt> is58* less than 1; or <tt>branchiness</tt> is greater than 1, or less59* or equal than 0; or <tt>size</tt> is less than 1.60*61*/62public NonbranchyTree(int numberOfNodes, float branchiness, int size) {63this(numberOfNodes, branchiness, size, null);64initTree();65}6667public NonbranchyTree(int numberOfNodes, float branchiness, int size, ExecutionController controller) {68this.numberOfNodes = numberOfNodes;69this.branchiness = branchiness;70this.size = size;71this.controller = controller;72initTree();73}7475private void initTree() {76if (numberOfNodes < 1) {77throw new IllegalArgumentException("Illegal number of nodes: "78+ numberOfNodes + ", must be at "79+ "least 1.");80}81if ( (branchiness >= 1) || (branchiness <= 0) ) {82throw new IllegalArgumentException("Illegal value of branchiness: "83+ numberOfNodes + ", must be at "84+ "greater than 0 and less than "85+ " 1.");86}87if (size < 1) {88throw new IllegalArgumentException("Illegal size of nodes: "89+ size + ", must be at least 1.");90}91// ensure that LocalRandom is loaded and has enough memory92LocalRandom.nextBoolean();93root = createTree(numberOfNodes, size);94}9596// Create a new tree with specified number of nodes and size of each node97private Node createTree(int numberOfNodes, int size) {98// Make sure we respect the controller and stop test after99// given time.100if (controller != null && !controller.continueExecution()) {101return null;102}103104Node node = new Node(size);105try {106if (numberOfNodes == 0) {107// No more nodes need to be built108return null;109} else if (numberOfNodes == 1) {110return node;111} else if (numberOfNodes == 2) {112node.left = createTree(1, size);113return node;114} else {115// Create a few nodes116if (makeRightNode()) {117// The node will have two sons118int leftNodes = 1 + LocalRandom.nextInt(numberOfNodes - 2);119int rightNodes = numberOfNodes - 1 - leftNodes;120121node.left = createTree(leftNodes, size);122node.right = createTree(rightNodes, size);123} else {124// The node will have just one son125Node leftTree = createTree(numberOfNodes - 1, size);126node.left = leftTree;127}128return node;129} // if130} catch(StackOverflowError e) {131// No more memory for such long tree132return node;133} catch(OutOfMemoryError e) {134// No more memory for such long tree135return node;136} // try137} // createTree()138139// Define the "branchiness" of the tree140private boolean makeRightNode() {141return (LocalRandom.nextFloat() < branchiness);142}143144/**145* Bends the tree. A son of a leaf of the tree is set to the root node.146*147*/148public void bend() {149bend(root);150}151152// Bend the tree: make a reference from a leat of the tree to the specified153// node154private void bend(Node markedNode) {155Node node = root;156157while ( (node.left != null) || (node.right != null) )158node = node.left;159node.right = markedNode;160}161162/**163* Prints the whole tree from the root to the defined PrintStream.164*165* @param out PrintStream to print the tree in166*167*/168public void print(PrintStream out) {169print(out, root);170}171172// Print the sub-tree from the specified node and down173private void print(PrintStream out, Node node) {174node.print(out);175if (node.left != null)176print(out, node.left);177if (node.right != null)178print(out, node.right);179}180}181182// The class defines a node of a tree183class Node {184Node left;185Node right;186byte[] core;187188Node(int size) {189left = null;190right = null;191core = new byte[size];192193// Initizlize the core array194for (int i = 0; i < size; i++)195core[i] = (byte) i;196}197198// Print the node info199void print(PrintStream out) {200out.println("node = " + this + " (" + left + ", " + right + ")");201}202}203204205