08855df46a
Reviewed-by: vlivanov, erikj, mseledtsov, gthornbr
142 lines
4.5 KiB
Java
142 lines
4.5 KiB
Java
/*
|
|
* Copyright (c) 2002, 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.sysdict;
|
|
|
|
import nsk.share.*;
|
|
|
|
/**
|
|
* A binary tree of class loaders.
|
|
*
|
|
* @see TreeNodesDenotation
|
|
*/
|
|
public class ClassLoadersBTree {
|
|
/**
|
|
* Cannot instantiate while a tree root and height
|
|
* are not specified.
|
|
*
|
|
* @see #ClassLoadersBTree(ClassLoader,int)
|
|
*/
|
|
protected ClassLoadersBTree() {
|
|
}
|
|
|
|
/**
|
|
* Given the <tt>root</tt> loader, instantiate a binary tree
|
|
* of loaders up to the given tree <tt>height</tt>.
|
|
*
|
|
* @see #getHeight()
|
|
* @see #getRoot()
|
|
* @see #getLoader(String)
|
|
* @see #getLoader(int,int)
|
|
*/
|
|
public ClassLoadersBTree(ClassLoader root, int height) {
|
|
if (height < 1)
|
|
throw new IllegalArgumentException("wrong height: " + height);
|
|
loaders = new ClassLoader [ height ] [];
|
|
for (int level=0; level<height; level++)
|
|
loaders[level] = new ClassLoader [1 << level];
|
|
loaders[0][0] = root;
|
|
generateSubtree("");
|
|
}
|
|
private void generateSubtree(String name) {
|
|
int level = name.length();
|
|
int height = loaders.length;
|
|
if (level+1 == height)
|
|
return;
|
|
String nameL = name + "L";
|
|
String nameR = name + "R";
|
|
int[] index = denotation.indexFor(name);
|
|
int[] indexL = denotation.indexFor(nameL);
|
|
int[] indexR = denotation.indexFor(nameR);
|
|
// assertion: index[0] == level
|
|
// assertion: indexL[0] == indexR[0] == level+1
|
|
int item = index[1];
|
|
int itemL = indexL[1];
|
|
int itemR = indexR[1];
|
|
ClassLoader parent = loaders[level][item];
|
|
ClassLoader childL = new DummyClassLoader(parent);
|
|
ClassLoader childR = new DummyClassLoader(parent); // another item
|
|
loaders[level+1][itemL] = childL;
|
|
loaders[level+1][itemR] = childR;
|
|
generateSubtree(nameL);
|
|
generateSubtree(nameR);
|
|
}
|
|
|
|
private ClassLoader loaders[][]; // loaders[0][0] is root
|
|
private Denotation denotation = new TreeNodesDenotation();
|
|
|
|
/**
|
|
* Return the loader found at the given <tt>level</tt> of
|
|
* this loaders tree, and having the given <tt>item</tt>
|
|
* number at the enumeration of that <tt>level</tt>.
|
|
*
|
|
* <p>The value of <tt>level</tt> must be from <tt>0</tt>
|
|
* to <tt>getHeight()-1</tt>, and the <tt>item</tt> number
|
|
* must be from <tt>0</tt> to <tt>2<sup>level</sup>-1</tt>.
|
|
*
|
|
* @see #getHeight()
|
|
* @see #getRoot()
|
|
* @see #getLoader(String)
|
|
*/
|
|
public ClassLoader getLoader(int level, int item) {
|
|
return loaders[level][item];
|
|
}
|
|
|
|
/**
|
|
* Return the loader having the giving <tt>name</tt> at
|
|
* the standard denotation of binary tree nodes.
|
|
*
|
|
* @see #getHeight()
|
|
* @see #getRoot()
|
|
* @see #getLoader(int,int)
|
|
*/
|
|
public ClassLoader getLoader(String name) {
|
|
int[] index = denotation.indexFor(name);
|
|
int level = index[0];
|
|
int item = index[1];
|
|
return loaders[level][item];
|
|
}
|
|
|
|
/**
|
|
* Return the tree's height.
|
|
*
|
|
* @see #ClassLoadersBTree(ClassLoader,int)
|
|
* @see #getLoader(int,int)
|
|
* @see #getLoader(String)
|
|
*/
|
|
public int getHeight() {
|
|
return loaders.length;
|
|
}
|
|
|
|
/**
|
|
* Return the tree's root loader.
|
|
*
|
|
* @see #ClassLoadersBTree(ClassLoader,int)
|
|
* @see #getLoader(int,int)
|
|
* @see #getLoader(String)
|
|
*/
|
|
public ClassLoader getRoot() {
|
|
return loaders[0][0];
|
|
}
|
|
}
|