File: NonbranchyTree.java

package info (click to toggle)
openjdk-11-jre-dcevm 11.0.15%2B1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 221,420 kB
  • sloc: java: 1,363,561; cpp: 967,919; ansic: 69,480; xml: 62,475; sh: 8,106; asm: 3,475; python: 1,667; javascript: 943; makefile: 397; sed: 172; perl: 114
file content (206 lines) | stat: -rw-r--r-- 7,292 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
 * Copyright (c) 2003, 2018, 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 nsk.share.gc;

import java.io.*;
import java.util.*;

import nsk.share.test.ExecutionController;

/**
 * <tt>NonbranchyTree</tt> defines a tree structure. Each node of the tree
 * always has one son. A node may have the second son with probability
 * <tt>branchiness</tt>.
 */
public class NonbranchyTree {

    /** Minimal size of each node (in bytes) */
    public final static int MIN_NODE_SIZE = 20;
    private Node root;
    private Random random;
    private int numberOfNodes;
    private float branchiness;
    private int size;
    private ExecutionController controller;

    /**
     * Creates a new tree with number of nodes not more than
     * <tt>numberOfNodes</tt>. The implementation uses recursion to build the
     * tree, so if <tt>StackOverflowError</tt> or <tt>OutOfMemoryError</tt> is
     * thrown, the recursion is stopped and the method finishes building of the
     * tree. Each node consists of <tt>byte[]</tt> of length <tt>size</tt>.
     *
     * @param numberOfNodes maximum number of nodes for the tree.
     * @param branchiness probability for each node to have the second son.
     * @param size number of bytes to store in a node.
     *
     * @throws <i>IllegalArgumentException</i> if <tt>numberOfNodes</tt> is
     *         less than 1; or <tt>branchiness</tt> is greater than 1, or less
     *         or equal than 0; or <tt>size</tt> is less than 1.
     *
     */
    public NonbranchyTree(int numberOfNodes, float branchiness, int size) {
        this(numberOfNodes, branchiness, size, new Random(System.currentTimeMillis()), null);
        initTree();
    }

    public NonbranchyTree(int numberOfNodes, float branchiness, int size, ExecutionController controller) {
        this(numberOfNodes, branchiness, size, new Random(System.currentTimeMillis()), controller);
        initTree();
    }

    private NonbranchyTree(int numberOfNodes, float branchiness, int size, Random random, ExecutionController controller) {
        this.numberOfNodes = numberOfNodes;
        this.branchiness = branchiness;
        this.size = size;
        this.random = random;
        this.controller = controller;
    }

    private void initTree() {
        if (numberOfNodes < 1) {
            throw new IllegalArgumentException("Illegal number of nodes: "
                                             + numberOfNodes + ", must be at "
                                             + "least 1.");
        }
        if ( (branchiness >= 1) || (branchiness <= 0) ) {
            throw new IllegalArgumentException("Illegal value of branchiness: "
                                             + numberOfNodes + ", must be at "
                                             + "greater than 0 and less than "
                                             + " 1.");
        }
        if (size < 1) {
            throw new IllegalArgumentException("Illegal size of nodes: "
                                             + size + ", must be at least 1.");
        }
        root = createTree(numberOfNodes, size);
    }

    // Create a new tree with specified number of nodes and size of each node
    private Node createTree(int numberOfNodes, int size) {
        // Make sure we respect the controller and stop test after
        // given time.
        if (controller != null && !controller.continueExecution()) {
            return null;
        }

        Node node = new Node(size);
        try {
            if (numberOfNodes == 0) {
                // No more nodes need to be built
                return null;
            } else if (numberOfNodes == 1) {
                return node;
            } else if (numberOfNodes == 2) {
                node.left = createTree(1, size);
                return node;
            } else {
                // Create a few nodes
                if (makeRightNode()) {
                    // The node will have two sons
                    int leftNodes = 1 + random.nextInt(numberOfNodes - 2);
                    int rightNodes = numberOfNodes - 1 - leftNodes;

                    node.left = createTree(leftNodes, size);
                    node.right = createTree(rightNodes, size);
                } else {
                    // The node will have just one son
                    Node leftTree = createTree(numberOfNodes - 1, size);
                    node.left = leftTree;
                }
                return node;
            } // if
        } catch(StackOverflowError e) {
            // No more memory for such long tree
            return node;
        } catch(OutOfMemoryError e) {
            // No more memory for such long tree
            return node;
        } // try
    } // createTree()

    // Define the "branchiness" of the tree
    private boolean makeRightNode() {
        return (random.nextFloat() < branchiness);
    }

    /**
     * Bends the tree. A son of a leaf of the tree is set to the root node.
     *
     */
    public void bend() {
        bend(root);
    }

    // Bend the tree: make a reference from a leat of the tree to the specified
    // node
    private void bend(Node markedNode) {
        Node node = root;

        while ( (node.left != null) || (node.right != null) )
            node = node.left;
        node.right = markedNode;
    }

    /**
     * Prints the whole tree from the root to the defined PrintStream.
     *
     * @param out PrintStream to print the tree in
     *
     */
    public void print(PrintStream out) {
        print(out, root);
    }

    // Print the sub-tree from the specified node and down
    private void print(PrintStream out, Node node) {
        node.print(out);
        if (node.left != null)
            print(out, node.left);
        if (node.right != null)
            print(out, node.right);
    }
}

// The class defines a node of a tree
class Node {
    Node left;
    Node right;
    byte[] core;

    Node(int size) {
        left = null;
        right = null;
        core = new byte[size];

        // Initizlize the core array
        for (int i = 0; i < size; i++)
            core[i] = (byte) i;
    }

    // Print the node info
    void print(PrintStream out) {
        out.println("node = " + this + " (" + left + ", " + right + ")");
    }
}