Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/IntervalTree.java
41161 views
/*1* Copyright (c) 2000, 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*22*/2324package sun.jvm.hotspot.utilities;2526/** Derived from the example in Section 15.3 of CLR. */2728import java.io.PrintStream;29import java.util.ArrayList;30import java.util.Comparator;31import java.util.List;3233public class IntervalTree extends RBTree {34private Comparator<Object> endpointComparator;3536/** This constructor takes only one comparator: one which operates37upon the endpoints of the Intervals this tree will store. It38constructs an internal "interval comparator" out of this one. */39public IntervalTree(Comparator<Object> endpointComparator) {40super(new IntervalComparator(endpointComparator));41this.endpointComparator = endpointComparator;42}4344public void insert(Interval interval, Object data) {45IntervalNode node = new IntervalNode(interval, endpointComparator, data);46insertNode(node);47}4849/** Returns a List<IntervalNode> indicating which nodes'50intervals were intersected by the given query interval. It is51guaranteed that these nodes will be returned sorted by52increasing low endpoint. */53public List<IntervalNode> findAllNodesIntersecting(Interval interval) {54List<IntervalNode> retList = new ArrayList<>();55searchForIntersectingNodesFrom((IntervalNode) getRoot(), interval, retList);56return retList;57}5859public void print() {60printOn(System.out);61}6263public void printOn(PrintStream tty) {64printFromNode(getRoot(), tty, 0);65}6667//----------------------------------------------------------------------68// Overridden internal functionality6970protected Object getNodeValue(RBNode node) {71return ((IntervalNode) node).getInterval();72}7374protected void verify() {75super.verify();76verifyFromNode(getRoot());77}7879//----------------------------------------------------------------------80// Internals only below this point81//8283private void verifyFromNode(RBNode node) {84if (node == null) {85return;86}8788// We already know that the red/black structure has been verified.89// What we need to find out is whether this node has been updated90// properly -- i.e., whether its notion of the maximum endpoint is91// correct.92IntervalNode intNode = (IntervalNode) node;93if (!intNode.getMaxEndpoint().equals(intNode.computeMaxEndpoint())) {94if (DEBUGGING && VERBOSE) {95print();96}97throw new RuntimeException("Node's max endpoint was not updated properly");98}99if (!intNode.getMinEndpoint().equals(intNode.computeMinEndpoint())) {100if (DEBUGGING && VERBOSE) {101print();102}103throw new RuntimeException("Node's min endpoint was not updated properly");104}105106verifyFromNode(node.getLeft());107verifyFromNode(node.getRight());108}109110static class IntervalComparator implements Comparator<Object> {111private Comparator<Object> endpointComparator;112113public IntervalComparator(Comparator<Object> endpointComparator) {114this.endpointComparator = endpointComparator;115}116117public int compare(Object o1, Object o2) {118Interval i1 = (Interval) o1;119Interval i2 = (Interval) o2;120return endpointComparator.compare(i1.getLowEndpoint(), i2.getLowEndpoint());121}122}123124private void searchForIntersectingNodesFrom(IntervalNode node,125Interval interval,126List<IntervalNode> resultList) {127if (node == null) {128return;129}130131// Inorder traversal (very important to guarantee sorted order)132133// Check to see whether we have to traverse the left subtree134IntervalNode left = (IntervalNode) node.getLeft();135if ((left != null) &&136(endpointComparator.compare(left.getMaxEndpoint(),137interval.getLowEndpoint()) > 0)) {138searchForIntersectingNodesFrom(left, interval, resultList);139}140141// Check for intersection with current node142if (node.getInterval().overlaps(interval, endpointComparator)) {143resultList.add(node);144}145146// Check to see whether we have to traverse the left subtree147IntervalNode right = (IntervalNode) node.getRight();148if ((right != null) &&149(endpointComparator.compare(interval.getHighEndpoint(),150right.getMinEndpoint()) > 0)) {151searchForIntersectingNodesFrom(right, interval, resultList);152}153}154155/** Debugging */156private void printFromNode(RBNode node, PrintStream tty, int indentDepth) {157for (int i = 0; i < indentDepth; i++) {158tty.print(" ");159}160161tty.print("-");162if (node == null) {163tty.println();164return;165}166167tty.println(" " + node +168" (min " + ((IntervalNode) node).getMinEndpoint() +169", max " + ((IntervalNode) node).getMaxEndpoint() + ")" +170((node.getColor() == RBColor.RED) ? " (red)" : " (black)"));171if (node.getLeft() != null) printFromNode(node.getLeft(), tty, indentDepth + 2);172if (node.getRight() != null) printFromNode(node.getRight(), tty, indentDepth + 2);173}174}175176177