1 /*
2  * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 package metaspace.stressHierarchy.common.classloader.tree;
24 
25 import java.util.*;
26 
27 import metaspace.stressHierarchy.common.classloader.StressClassloader;
28 import metaspace.stressHierarchy.common.generateHierarchy.NodeDescriptor;
29 
30 
31 /**
32  * Tree of hierarchy.
33  *
34  * The tree consists of {@link Nodes}s. Each node contains classloader {@link metaspace.stressHierarchy.common.classloader.StressClassloader} that is
35  * associated with one class (or interface) and can load only it. Edge in this
36  * tree correspond to parent relation between corresponding classloaders.
37  * Each classloader delegates to parent only after failed attempt to load class itself.
38  *
39  */
40 public class Tree {
41 
42     private final List<Node> allNodes = new LinkedList<Node>(); //order matters
43 
44     private int maxLevel;
45 
46     private Node root;
47 
cleanupLevel(int level)48     public void cleanupLevel(int level) {
49         for (Node node : getNodesInLevel(level)) {
50             node.cleanup();
51         }
52     }
53 
getMaxLevel()54     public int getMaxLevel() { return maxLevel; }
55 
getNodes()56     public List<Node> getNodes() {
57         return allNodes;
58     }
59 
getNodesInLevel(int level)60     public List<Node> getNodesInLevel(int level) {
61         List<Node> result = new LinkedList<Node>();
62         for (Iterator<Node> iter = allNodes.iterator(); iter.hasNext();) {
63             Node current = iter.next();
64             if (current.getLevel() == level) {
65                 result.add(current);
66             }
67         }
68         return result;
69     }
70 
findParent(Node node)71     private Node findParent(Node node) {
72         for (Iterator<Node> iter = allNodes.iterator(); iter.hasNext();) {
73             Node current = iter.next();
74             if (current.equals(node)) {
75                 return current;
76             }
77         }
78         return null;
79     }
80 
addNode(NodeDescriptor nodeDescriptor)81     public void addNode(NodeDescriptor nodeDescriptor) {
82         if (nodeDescriptor.level == 0) {
83             root = new Node(0, 0);
84             root.setClassLoader(new StressClassloader(nodeDescriptor, null));
85             allNodes.add(root);
86             return;
87         }
88         Node newOne = new Node(nodeDescriptor.level, nodeDescriptor.index);
89         Node parent = findParent(new Node(nodeDescriptor.level - 1, nodeDescriptor.parentIndex));
90 
91         //add a payload to new node
92         newOne.setClassLoader(new StressClassloader(nodeDescriptor, parent.getClassLoader()));
93 
94         newOne.setParent(parent);
95         allNodes.add(newOne);
96         maxLevel = maxLevel < newOne.getLevel() ? newOne.getLevel() : maxLevel;
97     }
98 
99 }
100