001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * The contents of this file are subject to the Sun Public License
028: * Version 1.0 (the "License"); you may not use this file except in
029: * compliance with the License. A copy of the License is available at
030: * http://www.sun.com/, and in the file LICENSE.html in the
031: * doc directory.
032: *
033: * The Original Code is HAT. The Initial Developer of the
034: * Original Code is Bill Foote, with contributions from others
035: * at JavaSoft/Sun. Portions created by Bill Foote and others
036: * at Javasoft/Sun are Copyright (C) 1997-2004. All Rights Reserved.
037: *
038: * In addition to the formal license, I ask that you don't
039: * change the history or donations files without permission.
040: *
041: */
042:
043: package com.sun.tools.hat.internal.model;
044:
045: import java.util.Vector;
046: import java.util.Hashtable;
047: import java.util.Enumeration;
048:
049: import com.sun.tools.hat.internal.util.ArraySorter;
050: import com.sun.tools.hat.internal.util.Comparer;
051:
052: /**
053: * @author A. Sundararajan
054: */
055:
056: public class ReachableObjects {
057: public ReachableObjects(JavaHeapObject root,
058: final ReachableExcludes excludes) {
059: this .root = root;
060:
061: final Hashtable<JavaHeapObject, JavaHeapObject> bag = new Hashtable<JavaHeapObject, JavaHeapObject>();
062: final Hashtable<String, String> fieldsExcluded = new Hashtable<String, String>(); //Bag<String>
063: final Hashtable<String, String> fieldsUsed = new Hashtable<String, String>(); // Bag<String>
064: JavaHeapObjectVisitor visitor = new AbstractJavaHeapObjectVisitor() {
065: public void visit(JavaHeapObject t) {
066: // Size is zero for things like integer fields
067: if (t != null && t.getSize() > 0 && bag.get(t) == null) {
068: bag.put(t, t);
069: t.visitReferencedObjects(this );
070: }
071: }
072:
073: public boolean mightExclude() {
074: return excludes != null;
075: }
076:
077: public boolean exclude(JavaClass clazz, JavaField f) {
078: if (excludes == null) {
079: return false;
080: }
081: String nm = clazz.getName() + "." + f.getName();
082: if (excludes.isExcluded(nm)) {
083: fieldsExcluded.put(nm, nm);
084: return true;
085: } else {
086: fieldsUsed.put(nm, nm);
087: return false;
088: }
089: }
090: };
091: // Put the closure of root and all objects reachable from root into
092: // bag (depth first), but don't include root:
093: visitor.visit(root);
094: bag.remove(root);
095:
096: // Now grab the elements into a vector, and sort it in decreasing size
097: JavaThing[] things = new JavaThing[bag.size()];
098: int i = 0;
099: for (Enumeration e = bag.elements(); e.hasMoreElements();) {
100: things[i++] = (JavaThing) e.nextElement();
101: }
102: ArraySorter.sort(things, new Comparer() {
103: public int compare(Object lhs, Object rhs) {
104: JavaThing left = (JavaThing) lhs;
105: JavaThing right = (JavaThing) rhs;
106: int diff = right.getSize() - left.getSize();
107: if (diff != 0) {
108: return diff;
109: }
110: return left.compareTo(right);
111: }
112: });
113: this .reachables = things;
114:
115: this .totalSize = root.getSize();
116: for (i = 0; i < things.length; i++) {
117: this .totalSize += things[i].getSize();
118: }
119:
120: excludedFields = getElements(fieldsExcluded);
121: usedFields = getElements(fieldsUsed);
122: }
123:
124: public JavaHeapObject getRoot() {
125: return root;
126: }
127:
128: public JavaThing[] getReachables() {
129: return reachables;
130: }
131:
132: public long getTotalSize() {
133: return totalSize;
134: }
135:
136: public String[] getExcludedFields() {
137: return excludedFields;
138: }
139:
140: public String[] getUsedFields() {
141: return usedFields;
142: }
143:
144: private String[] getElements(Hashtable ht) {
145: Object[] keys = ht.keySet().toArray();
146: int len = keys.length;
147: String[] res = new String[len];
148: System.arraycopy(keys, 0, res, 0, len);
149: ArraySorter.sortArrayOfStrings(res);
150: return res;
151: }
152:
153: private JavaHeapObject root;
154: private JavaThing[] reachables;
155: private String[] excludedFields;
156: private String[] usedFields;
157: private long totalSize;
158: }
|