View | Details | Raw Unified | Return to bug 123396
Collapse All | Expand All

(-)model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java (-6 / +27 lines)
Lines 18-26 Link Here
18
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.jdt.core.*;
20
import org.eclipse.jdt.core.*;
21
import org.eclipse.jdt.core.IClasspathEntry;
22
import org.eclipse.jdt.core.IPackageFragmentRoot;
23
import org.eclipse.jdt.core.JavaModelException;
24
import org.eclipse.jdt.internal.core.util.Util;
21
import org.eclipse.jdt.internal.core.util.Util;
25
import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
22
import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
26
23
Lines 38-46 Link Here
38
class JavaProjectElementInfo extends OpenableElementInfo {
35
class JavaProjectElementInfo extends OpenableElementInfo {
39
36
40
	static class ProjectCache {
37
	static class ProjectCache {
41
		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, Map rootToResolvedEntries) {
38
		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, HashtableOfArrayToObject isPackageCache, Map rootToResolvedEntries) {
42
			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
39
			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
43
			this.allPkgFragmentsCache = allPkgFragmentsCache;
40
			this.allPkgFragmentsCache = allPkgFragmentsCache;
41
			this.isPackageCache = isPackageCache;
44
			this.rootToResolvedEntries = rootToResolvedEntries;
42
			this.rootToResolvedEntries = rootToResolvedEntries;
45
		}
43
		}
46
		
44
		
Lines 54-59 Link Here
54
		 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)
52
		 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)
55
		 */
53
		 */
56
		public HashtableOfArrayToObject allPkgFragmentsCache;
54
		public HashtableOfArrayToObject allPkgFragmentsCache;
55
		
56
		/*
57
		 * A set of package names (String[]) that are known to be packages.
58
		 */
59
		public HashtableOfArrayToObject isPackageCache;
57
	
60
	
58
		public Map rootToResolvedEntries;		
61
		public Map rootToResolvedEntries;		
59
	}
62
	}
Lines 65-70 Link Here
65
	
68
	
66
	ProjectCache projectCache;
69
	ProjectCache projectCache;
67
	
70
	
71
	/*
72
	 * Adds the given name and its super names to the given set
73
	 * (e.g. for {"a", "b", "c"}, adds {"a", "b", "c"}, {"a", "b"}, and {"a"})
74
	 */
75
	public static void addNames(String[] name, HashtableOfArrayToObject set) {
76
		set.put(name, name);
77
		int length = name.length;
78
		for (int i = length-1; i > 0; i--) {
79
			String[] superName = new String[i];
80
			System.arraycopy(name, 0, superName, 0, i);
81
			set.put(superName, superName);
82
		}
83
	}
84
	
68
	/**
85
	/**
69
	 * Create and initialize a new instance of the receiver
86
	 * Create and initialize a new instance of the receiver
70
	 */
87
	 */
Lines 188-193 Link Here
188
				reverseMap.clear();
205
				reverseMap.clear();
189
			}
206
			}
190
			HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject();
207
			HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject();
208
			HashtableOfArrayToObject isPackageCache = new HashtableOfArrayToObject();
191
			for (int i = 0, length = roots.length; i < length; i++) {
209
			for (int i = 0, length = roots.length; i < length; i++) {
192
				IPackageFragmentRoot root = roots[i];
210
				IPackageFragmentRoot root = roots[i];
193
				IJavaElement[] frags = null;
211
				IJavaElement[] frags = null;
Lines 203-208 Link Here
203
					Object existing = fragmentsCache.get(pkgName);
221
					Object existing = fragmentsCache.get(pkgName);
204
					if (existing == null) {
222
					if (existing == null) {
205
						fragmentsCache.put(pkgName, root);
223
						fragmentsCache.put(pkgName, root);
224
						// cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
225
						// are actual packages
226
						addNames(pkgName, isPackageCache);
206
					} else {
227
					} else {
207
						if (existing instanceof PackageFragmentRoot) {
228
						if (existing instanceof PackageFragmentRoot) {
208
							fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
229
							fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
Lines 216-222 Link Here
216
					}
237
					}
217
				}
238
				}
218
			}
239
			}
219
			cache = new ProjectCache(roots, fragmentsCache, reverseMap);
240
			cache = new ProjectCache(roots, fragmentsCache, isPackageCache, reverseMap);
220
			this.projectCache = cache;
241
			this.projectCache = cache;
221
		}
242
		}
222
		return cache;
243
		return cache;
Lines 258-264 Link Here
258
	 */
279
	 */
259
	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
280
	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
260
		ProjectCache cache = getProjectCache(project);
281
		ProjectCache cache = getProjectCache(project);
261
		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries);
282
		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, cache.isPackageCache, workingCopies, cache.rootToResolvedEntries);
262
	}
283
	}
263
	
284
	
264
	/*
285
	/*
(-)model/org/eclipse/jdt/internal/core/NameLookup.java (-23 / +22 lines)
Lines 101-107 Link Here
101
	protected HashtableOfArrayToObject packageFragments;
101
	protected HashtableOfArrayToObject packageFragments;
102
	
102
	
103
	/*
103
	/*
104
	 * A set of names (String[]) that are not to be package names.
104
	 * A set of names (String[]) that are known to be package names.
105
	 * Value is not null for known package.
105
	 * Value is not null for known package.
106
	 */
106
	 */
107
	protected HashtableOfArrayToObject isPackageCache;
107
	protected HashtableOfArrayToObject isPackageCache;
Lines 121-127 Link Here
121
	public long timeSpentInSeekTypesInSourcePackage = 0;
121
	public long timeSpentInSeekTypesInSourcePackage = 0;
122
	public long timeSpentInSeekTypesInBinaryPackage = 0;
122
	public long timeSpentInSeekTypesInBinaryPackage = 0;
123
123
124
	public NameLookup(IPackageFragmentRoot[] packageFragmentRoots, HashtableOfArrayToObject packageFragments, ICompilationUnit[] workingCopies, Map rootToResolvedEntries) {
124
	public NameLookup(
125
			IPackageFragmentRoot[] packageFragmentRoots, 
126
			HashtableOfArrayToObject packageFragments, 
127
			HashtableOfArrayToObject isPackage, 
128
			ICompilationUnit[] workingCopies, 
129
			Map rootToResolvedEntries) {
125
		long start = -1;
130
		long start = -1;
126
		if (VERBOSE) {
131
		if (VERBOSE) {
127
			Util.verbose(" BUILDING NameLoopkup");  //$NON-NLS-1$
132
			Util.verbose(" BUILDING NameLoopkup");  //$NON-NLS-1$
Lines 131-142 Link Here
131
			start = System.currentTimeMillis();
136
			start = System.currentTimeMillis();
132
		}
137
		}
133
		this.packageFragmentRoots = packageFragmentRoots;
138
		this.packageFragmentRoots = packageFragmentRoots;
134
		try {
139
		if (workingCopies == null) {
135
			this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone();
140
			this.packageFragments = packageFragments;
136
		} catch (CloneNotSupportedException e1) {
141
			this.isPackageCache = isPackage;
137
			// ignore (implementation of HashtableOfArrayToObject supports cloning)
142
		} else {
138
		}
143
			// clone tables as we're adding packages from working copies
139
		if (workingCopies != null) {
144
			try {
145
				this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone();
146
				this.isPackageCache = (HashtableOfArrayToObject) isPackage.clone();
147
			} catch (CloneNotSupportedException e1) {
148
				// ignore (implementation of HashtableOfArrayToObject supports cloning)
149
			}
140
			this.typesInWorkingCopies = new HashMap();
150
			this.typesInWorkingCopies = new HashMap();
141
			for (int i = 0, length = workingCopies.length; i < length; i++) {
151
			for (int i = 0, length = workingCopies.length; i < length; i++) {
142
				ICompilationUnit workingCopy = workingCopies[i];
152
				ICompilationUnit workingCopy = workingCopies[i];
Lines 180-185 Link Here
180
				Object existing = this.packageFragments.get(pkgName);
190
				Object existing = this.packageFragments.get(pkgName);
181
				if (existing == null) {
191
				if (existing == null) {
182
					this.packageFragments.put(pkgName, root);
192
					this.packageFragments.put(pkgName, root);
193
					// cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
194
					// are actual packages
195
					JavaProjectElementInfo.addNames(pkgName, this.isPackageCache);
183
				} else {
196
				} else {
184
					if (existing instanceof PackageFragmentRoot) {
197
					if (existing instanceof PackageFragmentRoot) {
185
						if (!existing.equals(root))
198
						if (!existing.equals(root))
Lines 204-226 Link Here
204
			}
217
			}
205
		}
218
		}
206
		
219
		
207
		// cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
208
		// are actual packages
209
		this.isPackageCache = new HashtableOfArrayToObject();
210
		for (int i = 0, size = this.packageFragments.keyTable.length; i < size; i++) {
211
			String[] pkgName = (String[]) this.packageFragments.keyTable[i];
212
			if (pkgName == null) continue;
213
			this.isPackageCache.put(pkgName, pkgName);
214
			int length = pkgName.length;
215
			for (int j = length-1; j > 0; j--) {
216
				String[] subPkgName = new String[j];
217
				System.arraycopy(pkgName, 0, subPkgName, 0, j);
218
				this.isPackageCache.put(subPkgName, subPkgName);
219
			}
220
		}
221
		this.rootToResolvedEntries = rootToResolvedEntries;
220
		this.rootToResolvedEntries = rootToResolvedEntries;
222
        if (VERBOSE) {
221
        if (VERBOSE) {
223
            Util.verbose(" -> spent: " + (start - System.currentTimeMillis()) + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
222
            Util.verbose(" -> spent: " + (System.currentTimeMillis() - start) + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
224
        }
223
        }
225
	}
224
	}
226
225
(-)model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java (-1 / +1 lines)
Lines 96-102 Link Here
96
	
96
	
97
	private int hashCode(Object[] element, int length) {
97
	private int hashCode(Object[] element, int length) {
98
		int hash = 0;
98
		int hash = 0;
99
		for (int i = 0; i < length; i++)
99
		for (int i = length-1; i >= 0; i--)
100
			hash = Util.combineHashCodes(hash, element[i].hashCode());
100
			hash = Util.combineHashCodes(hash, element[i].hashCode());
101
		return hash & 0x7FFFFFFF;
101
		return hash & 0x7FFFFFFF;
102
	}
102
	}
(-)model/org/eclipse/jdt/internal/core/util/Util.java (-1 / +3 lines)
Lines 500-506 Link Here
500
500
501
		int len = a.length;
501
		int len = a.length;
502
		if (len != b.length) return false;
502
		if (len != b.length) return false;
503
		for (int i = 0; i < len; ++i) {
503
		// walk array from end to beginning as this optimizes package name cases 
504
		// where the first part is always the same (e.g. org.eclipse.jdt)
505
		for (int i = len-1; i >= 0; i--) {
504
			if (a[i] == null) {
506
			if (a[i] == null) {
505
				if (b[i] != null) return false;
507
				if (b[i] != null) return false;
506
			} else {
508
			} else {

Return to bug 123396