Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 65764 Details for
Bug 182930
JavaModelCache's size grows when displaying type hierarchy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch against R3_2_maintenance
182930j.txt (text/plain), 18.37 KB, created by
Jerome Lanneluc
on 2007-05-03 10:04:42 EDT
(
hide
)
Description:
Patch against R3_2_maintenance
Filename:
MIME Type:
Creator:
Jerome Lanneluc
Created:
2007-05-03 10:04:42 EDT
Size:
18.37 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: model/org/eclipse/jdt/internal/core/JavaProject.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java,v >retrieving revision 1.370 >diff -u -r1.370 JavaProject.java >--- model/org/eclipse/jdt/internal/core/JavaProject.java 2 May 2006 15:01:33 -0000 1.370 >+++ model/org/eclipse/jdt/internal/core/JavaProject.java 3 May 2007 14:01:08 -0000 >@@ -63,6 +63,7 @@ > import org.eclipse.jdt.core.eval.IEvaluationContext; > import org.eclipse.jdt.internal.compiler.util.ObjectVector; > import org.eclipse.jdt.internal.compiler.util.SuffixConstants; >+import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache; > import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper; > import org.eclipse.jdt.internal.core.util.MementoTokenizer; > import org.eclipse.jdt.internal.core.util.Messages; >@@ -1945,6 +1946,10 @@ > public IProject getProject() { > return this.project; > } >+ >+ public ProjectCache getProjectCache() throws JavaModelException { >+ return ((JavaProjectElementInfo) getElementInfo()).getProjectCache(this); >+ } > > /** > * @see IJavaProject >Index: model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java,v >retrieving revision 1.40 >diff -u -r1.40 JavaProjectElementInfo.java >--- model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java 29 Mar 2006 03:08:47 -0000 1.40 >+++ model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java 3 May 2007 14:01:08 -0000 >@@ -18,6 +18,7 @@ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IPath; > import org.eclipse.jdt.core.*; >+import org.eclipse.jdt.internal.core.util.HashSetOfArray; > import org.eclipse.jdt.internal.core.util.Util; > import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject; > >@@ -33,13 +34,14 @@ > > /* package */ > class JavaProjectElementInfo extends OpenableElementInfo { >+ >+ static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0]; > > static class ProjectCache { >- ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, HashtableOfArrayToObject isPackageCache, Map rootToResolvedEntries) { >+ ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, Map rootToResolvedEntries, Map pkgFragmentsCaches) { > this.allPkgFragmentRootsCache = allPkgFragmentRootsCache; >- this.allPkgFragmentsCache = allPkgFragmentsCache; >- this.isPackageCache = isPackageCache; > this.rootToResolvedEntries = rootToResolvedEntries; >+ this.pkgFragmentsCaches = pkgFragmentsCaches; > } > > /* >@@ -49,15 +51,16 @@ > > /* > * A cache of all package fragments in this project. >- * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name) >+ * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)) > */ > public HashtableOfArrayToObject allPkgFragmentsCache; > > /* >- * A set of package names (String[]) that are known to be packages. >+ * A cache of package fragments for each package fragment root of this project >+ * (a map from IPackageFragmentRoot to a set of String[] (the package name)) > */ >- public HashtableOfArrayToObject isPackageCache; >- >+ public Map pkgFragmentsCaches; >+ > public Map rootToResolvedEntries; > } > >@@ -72,13 +75,12 @@ > * Adds the given name and its super names to the given set > * (e.g. for {"a", "b", "c"}, adds {"a", "b", "c"}, {"a", "b"}, and {"a"}) > */ >- public static void addNames(String[] name, HashtableOfArrayToObject set) { >- set.put(name, name); >- int length = name.length; >- for (int i = length-1; i > 0; i--) { >- String[] superName = new String[i]; >- System.arraycopy(name, 0, superName, 0, i); >- set.put(superName, superName); >+ static void addSuperPackageNames(String[] pkgName, HashtableOfArrayToObject packageFragments) { >+ for (int i = pkgName.length-1; i > 0; i--) { >+ if (packageFragments.getKey(pkgName, i) == null) { >+ System.arraycopy(pkgName, 0, pkgName = new String[i], 0, i); >+ packageFragments.put(pkgName, NO_ROOTS); >+ } > } > } > >@@ -204,45 +206,22 @@ > roots = new IPackageFragmentRoot[0]; > reverseMap.clear(); > } >- HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject(); >- HashtableOfArrayToObject isPackageCache = new HashtableOfArrayToObject(); >- for (int i = 0, length = roots.length; i < length; i++) { >+ >+ HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots; >+ HashMap pkgFragmentsCaches = new HashMap(); >+ int length = roots.length; >+ for (int i = 0; i < length; i++) { > IPackageFragmentRoot root = roots[i]; >- IJavaElement[] frags = null; >- try { >- if (root.isArchive() && !root.isOpen()) { >- JarPackageFragmentRootInfo info = new JarPackageFragmentRootInfo(); >- ((JarPackageFragmentRoot) root).computeChildren(info, new HashMap()); >- frags = info.children; >- } else >- frags = root.getChildren(); >- } catch (JavaModelException e) { >- // root doesn't exist: ignore >- continue; >- } >- for (int j = 0, length2 = frags.length; j < length2; j++) { >- PackageFragment fragment= (PackageFragment) frags[j]; >- String[] pkgName = fragment.names; >- Object existing = fragmentsCache.get(pkgName); >- if (existing == null) { >- fragmentsCache.put(pkgName, root); >- // cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) >- // are actual packages >- addNames(pkgName, isPackageCache); >- } else { >- if (existing instanceof PackageFragmentRoot) { >- fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root}); >- } else { >- IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) existing; >- IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1]; >- System.arraycopy(entry, 0, copy, 0, entry.length); >- copy[entry.length]= root; >- fragmentsCache.put(pkgName, copy); >- } >- } >+ DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath()); >+ if (rootInfo == null || rootInfo.project.equals(project)) { >+ // compute fragment cache >+ HashSetOfArray fragmentsCache = new HashSetOfArray(); >+ initializePackageNames(root, fragmentsCache); >+ pkgFragmentsCaches.put(root, fragmentsCache); > } > } >- cache = new ProjectCache(roots, fragmentsCache, isPackageCache, reverseMap); >+ >+ cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches); > this.projectCache = cache; > } > return cache; >@@ -258,6 +237,24 @@ > } > return this.nonJavaResources; > } >+ >+ private void initializePackageNames(IPackageFragmentRoot root, HashSetOfArray fragmentsCache) { >+ IJavaElement[] frags = null; >+ try { >+ if (!root.isOpen()) { >+ PackageFragmentRootInfo info = root.isArchive() ? new JarPackageFragmentRootInfo() : new PackageFragmentRootInfo(); >+ ((PackageFragmentRoot) root).computeChildren(info, new HashMap()); >+ frags = info.children; >+ } else >+ frags = root.getChildren(); >+ } catch (JavaModelException e) { >+ // root doesn't exist: ignore >+ return; >+ } >+ for (int j = 0, length2 = frags.length; j < length2; j++) { >+ fragmentsCache.add(((PackageFragment) frags[j]).names); >+ } >+ } > > /* > * Returns whether the given path is a classpath entry or an output location. >@@ -284,7 +281,62 @@ > */ > NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) { > ProjectCache cache = getProjectCache(project); >- return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, cache.isPackageCache, workingCopies, cache.rootToResolvedEntries); >+ HashtableOfArrayToObject allPkgFragmentsCache = cache.allPkgFragmentsCache; >+ if (allPkgFragmentsCache == null) { >+ HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots; >+ IPackageFragmentRoot[] allRoots = cache.allPkgFragmentRootsCache; >+ int length = allRoots.length; >+ allPkgFragmentsCache = new HashtableOfArrayToObject(); >+ for (int i = 0; i < length; i++) { >+ IPackageFragmentRoot root = allRoots[i]; >+ DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath()); >+ JavaProject rootProject = rootInfo == null ? project : rootInfo.project; >+ HashSetOfArray fragmentsCache; >+ if (rootProject.equals(project)) { >+ // retrieve package fragments cache from this project >+ fragmentsCache = (HashSetOfArray) cache.pkgFragmentsCaches.get(root); >+ } else { >+ // retrieve package fragments cache from the root's project >+ ProjectCache rootProjectCache; >+ try { >+ rootProjectCache = rootProject.getProjectCache(); >+ } catch (JavaModelException e) { >+ // project doesn't exit >+ continue; >+ } >+ fragmentsCache = (HashSetOfArray) rootProjectCache.pkgFragmentsCaches.get(root); >+ } >+ if (fragmentsCache == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183833 >+ fragmentsCache = new HashSetOfArray(); >+ initializePackageNames(root, fragmentsCache); >+ } >+ Object[][] set = fragmentsCache.set; >+ for (int j = 0, length2 = set.length; j < length2; j++) { >+ String[] pkgName = (String[]) set[j]; >+ if (pkgName == null) >+ continue; >+ Object existing = allPkgFragmentsCache.get(pkgName); >+ if (existing == null || existing == NO_ROOTS) { >+ allPkgFragmentsCache.put(pkgName, root); >+ // ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) >+ // are also in the map >+ addSuperPackageNames(pkgName, allPkgFragmentsCache); >+ } else { >+ if (existing instanceof PackageFragmentRoot) { >+ allPkgFragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root}); >+ } else { >+ IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing; >+ int rootLength = roots.length; >+ System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength); >+ roots[rootLength] = root; >+ allPkgFragmentsCache.put(pkgName, roots); >+ } >+ } >+ } >+ } >+ cache.allPkgFragmentsCache = allPkgFragmentsCache; >+ } >+ return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries); > } > > /* >Index: model/org/eclipse/jdt/internal/core/NameLookup.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java,v >retrieving revision 1.110 >diff -u -r1.110 NameLookup.java >--- model/org/eclipse/jdt/internal/core/NameLookup.java 29 Mar 2006 03:08:47 -0000 1.110 >+++ model/org/eclipse/jdt/internal/core/NameLookup.java 3 May 2007 14:01:08 -0000 >@@ -125,12 +125,6 @@ > */ > protected HashtableOfArrayToObject packageFragments; > >- /* >- * A set of names (String[]) that are known to be package names. >- * Value is not null for known package. >- */ >- protected HashtableOfArrayToObject isPackageCache; >- > /** > * Reverse map from root path to corresponding resolved CP entry > * (so as to be able to figure inclusion/exclusion rules) >@@ -149,7 +143,6 @@ > public NameLookup( > IPackageFragmentRoot[] packageFragmentRoots, > HashtableOfArrayToObject packageFragments, >- HashtableOfArrayToObject isPackage, > ICompilationUnit[] workingCopies, > Map rootToResolvedEntries) { > long start = -1; >@@ -163,12 +156,10 @@ > this.packageFragmentRoots = packageFragmentRoots; > if (workingCopies == null) { > this.packageFragments = packageFragments; >- this.isPackageCache = isPackage; > } else { > // clone tables as we're adding packages from working copies > try { > this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone(); >- this.isPackageCache = (HashtableOfArrayToObject) isPackage.clone(); > } catch (CloneNotSupportedException e1) { > // ignore (implementation of HashtableOfArrayToObject supports cloning) > } >@@ -213,11 +204,11 @@ > IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent(); > String[] pkgName = pkg.names; > Object existing = this.packageFragments.get(pkgName); >- if (existing == null) { >+ if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) { > this.packageFragments.put(pkgName, root); >- // cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) >- // are actual packages >- JavaProjectElementInfo.addNames(pkgName, this.isPackageCache); >+ // ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) >+ // are also in the map >+ JavaProjectElementInfo.addSuperPackageNames(pkgName, this.packageFragments); > } else { > if (existing instanceof PackageFragmentRoot) { > if (!existing.equals(root)) >@@ -778,7 +769,7 @@ > } > > public boolean isPackage(String[] pkgName) { >- return this.isPackageCache.get(pkgName) != null; >+ return this.packageFragments.get(pkgName) != null; > } > > /** >Index: model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java >=================================================================== >RCS file: model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java >diff -N model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,149 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2007 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.util; >+ >+/** >+ * HashSet of Object[] >+ */ >+public final class HashSetOfArray implements Cloneable { >+ >+ // to avoid using Enumerations, walk the individual tables skipping nulls >+ public Object[][] set; >+ >+ public int elementSize; // number of elements in the table >+ int threshold; >+ >+ public HashSetOfArray() { >+ this(13); >+ } >+ >+ public HashSetOfArray(int size) { >+ >+ this.elementSize = 0; >+ this.threshold = size; // size represents the expected number of elements >+ int extraRoom = (int) (size * 1.75f); >+ if (this.threshold == extraRoom) >+ extraRoom++; >+ this.set = new Object[extraRoom][]; >+ } >+ >+ public Object clone() throws CloneNotSupportedException { >+ HashSetOfArray result = (HashSetOfArray) super.clone(); >+ result.elementSize = this.elementSize; >+ result.threshold = this.threshold; >+ >+ int length = this.set.length; >+ result.set = new Object[length][]; >+ System.arraycopy(this.set, 0, result.set, 0, length); >+ >+ return result; >+ } >+ >+ public boolean contains(Object[] array) { >+ int length = this.set.length; >+ int index = hashCode(array) % length; >+ int arrayLength = array.length; >+ Object[] currentArray; >+ while ((currentArray = this.set[index]) != null) { >+ if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array)) >+ return true; >+ if (++index == length) { >+ index = 0; >+ } >+ } >+ return false; >+ } >+ >+ private int hashCode(Object[] element) { >+ return hashCode(element, element.length); >+ } >+ >+ private int hashCode(Object[] element, int length) { >+ int hash = 0; >+ for (int i = length-1; i >= 0; i--) >+ hash = Util.combineHashCodes(hash, element[i].hashCode()); >+ return hash & 0x7FFFFFFF; >+ } >+ >+ public Object add(Object[] array) { >+ int length = this.set.length; >+ int index = hashCode(array) % length; >+ int arrayLength = array.length; >+ Object[] currentArray; >+ while ((currentArray = this.set[index]) != null) { >+ if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array)) >+ return this.set[index] = array; >+ if (++index == length) { >+ index = 0; >+ } >+ } >+ this.set[index] = array; >+ >+ // assumes the threshold is never equal to the size of the table >+ if (++this.elementSize > threshold) >+ rehash(); >+ return array; >+ } >+ >+ public Object remove(Object[] array) { >+ int length = this.set.length; >+ int index = hashCode(array) % length; >+ int arrayLength = array.length; >+ Object[] currentArray; >+ while ((currentArray = this.set[index]) != null) { >+ if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array)) { >+ Object existing = this.set[index]; >+ this.elementSize--; >+ this.set[index] = null; >+ rehash(); >+ return existing; >+ } >+ if (++index == length) { >+ index = 0; >+ } >+ } >+ return null; >+ } >+ >+ private void rehash() { >+ >+ HashSetOfArray newHashSet = new HashSetOfArray(elementSize * 2); // double the number of expected elements >+ Object[] currentArray; >+ for (int i = this.set.length; --i >= 0;) >+ if ((currentArray = this.set[i]) != null) >+ newHashSet.add(currentArray); >+ >+ this.set = newHashSet.set; >+ this.threshold = newHashSet.threshold; >+ } >+ >+ public int size() { >+ return elementSize; >+ } >+ >+ public String toString() { >+ StringBuffer buffer = new StringBuffer(); >+ Object[] element; >+ for (int i = 0, length = this.set.length; i < length; i++) >+ if ((element = this.set[i]) != null) { >+ buffer.append('{'); >+ for (int j = 0, length2 = element.length; j < length2; j++) { >+ buffer.append(element[j]); >+ if (j != length2-1) >+ buffer.append(", "); //$NON-NLS-1$ >+ } >+ buffer.append("}"); //$NON-NLS-1$ >+ if (i != length-1) >+ buffer.append('\n'); >+ } >+ return buffer.toString(); >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 182930
:
64162
|
64576
|
64656
|
64691
|
64707
| 65764