Lines 1-5
Link Here
|
1 |
/******************************************************************************* |
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2006 IBM Corporation and others. |
2 |
* Copyright (c) 2000, 2007 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
Lines 26-33
Link Here
|
26 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
26 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
27 |
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
27 |
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
28 |
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; |
28 |
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; |
|
|
29 |
import org.eclipse.jdt.internal.compiler.util.SimpleSet; |
29 |
import org.eclipse.jdt.internal.core.*; |
30 |
import org.eclipse.jdt.internal.core.*; |
30 |
import org.eclipse.jdt.internal.core.index.Index; |
31 |
import org.eclipse.jdt.internal.core.index.*; |
31 |
import org.eclipse.jdt.internal.core.search.BasicSearchEngine; |
32 |
import org.eclipse.jdt.internal.core.search.BasicSearchEngine; |
32 |
import org.eclipse.jdt.internal.core.search.PatternSearchJob; |
33 |
import org.eclipse.jdt.internal.core.search.PatternSearchJob; |
33 |
import org.eclipse.jdt.internal.core.search.processing.IJob; |
34 |
import org.eclipse.jdt.internal.core.search.processing.IJob; |
Lines 37-47
Link Here
|
37 |
|
38 |
|
38 |
public class IndexManager extends JobManager implements IIndexConstants { |
39 |
public class IndexManager extends JobManager implements IIndexConstants { |
39 |
|
40 |
|
|
|
41 |
// key = containerPath, value = indexLocation path |
42 |
// indexLocation path is created by appending an index file name to the getJavaPluginWorkingLocation() path |
40 |
public SimpleLookupTable indexLocations = new SimpleLookupTable(); |
43 |
public SimpleLookupTable indexLocations = new SimpleLookupTable(); |
41 |
/* |
44 |
// key = indexLocation path, value = an index |
42 |
* key = an IPath, value = an Index |
45 |
private SimpleLookupTable indexes = new SimpleLookupTable(); |
43 |
*/ |
|
|
44 |
private Map indexes = new HashMap(5); |
45 |
|
46 |
|
46 |
/* need to save ? */ |
47 |
/* need to save ? */ |
47 |
private boolean needToSave = false; |
48 |
private boolean needToSave = false; |
Lines 49-57
Link Here
|
49 |
private IPath javaPluginLocation = null; |
50 |
private IPath javaPluginLocation = null; |
50 |
|
51 |
|
51 |
/* can only replace a current state if its less than the new one */ |
52 |
/* can only replace a current state if its less than the new one */ |
|
|
53 |
// key = indexLocation path, value = index state integer |
52 |
private SimpleLookupTable indexStates = null; |
54 |
private SimpleLookupTable indexStates = null; |
53 |
private File savedIndexNamesFile = |
55 |
private File savedIndexNamesFile = new File(getSavedIndexesDirectory(), "savedIndexNames.txt"); //$NON-NLS-1$ |
54 |
new File(getJavaPluginWorkingLocation().append("savedIndexNames.txt").toOSString()); //$NON-NLS-1$ |
|
|
55 |
public static Integer SAVED_STATE = new Integer(0); |
56 |
public static Integer SAVED_STATE = new Integer(0); |
56 |
public static Integer UPDATING_STATE = new Integer(1); |
57 |
public static Integer UPDATING_STATE = new Integer(1); |
57 |
public static Integer UNKNOWN_STATE = new Integer(2); |
58 |
public static Integer UNKNOWN_STATE = new Integer(2); |
Lines 60-66
Link Here
|
60 |
public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) { |
61 |
public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) { |
61 |
// newIndexState is either UPDATING_STATE or REBUILDING_STATE |
62 |
// newIndexState is either UPDATING_STATE or REBUILDING_STATE |
62 |
// must tag the index as inconsistent, in case we exit before the update job is started |
63 |
// must tag the index as inconsistent, in case we exit before the update job is started |
63 |
String indexLocation = computeIndexLocation(containerPath); |
64 |
IPath indexLocation = computeIndexLocation(containerPath); |
64 |
Object state = getIndexStates().get(indexLocation); |
65 |
Object state = getIndexStates().get(indexLocation); |
65 |
Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; |
66 |
Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; |
66 |
if (currentIndexState.equals(REBUILDING_STATE)) return; // already rebuilding the index |
67 |
if (currentIndexState.equals(REBUILDING_STATE)) return; // already rebuilding the index |
Lines 82-88
Link Here
|
82 |
if (JavaCore.getPlugin() == null) return; |
83 |
if (JavaCore.getPlugin() == null) return; |
83 |
SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); |
84 |
SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); |
84 |
SearchDocument document = participant.getDocument(resource.getFullPath().toString()); |
85 |
SearchDocument document = participant.getDocument(resource.getFullPath().toString()); |
85 |
String indexLocation = computeIndexLocation(containerPath); |
86 |
IPath indexLocation = computeIndexLocation(containerPath); |
86 |
scheduleDocumentIndexing(document, containerPath, indexLocation, participant); |
87 |
scheduleDocumentIndexing(document, containerPath, indexLocation, participant); |
87 |
} |
88 |
} |
88 |
/** |
89 |
/** |
Lines 94-149
Link Here
|
94 |
SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); |
95 |
SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); |
95 |
SearchDocument document = participant.getDocument(resource.getFullPath().toString()); |
96 |
SearchDocument document = participant.getDocument(resource.getFullPath().toString()); |
96 |
((InternalSearchDocument) document).parser = parser; |
97 |
((InternalSearchDocument) document).parser = parser; |
97 |
String indexLocation = computeIndexLocation(containerPath); |
98 |
IPath indexLocation = computeIndexLocation(containerPath); |
98 |
scheduleDocumentIndexing(document, containerPath, indexLocation, participant); |
99 |
scheduleDocumentIndexing(document, containerPath, indexLocation, participant); |
99 |
} |
100 |
} |
100 |
/* |
101 |
/* |
101 |
* Removes unused indexes from disk. |
102 |
* Removes unused indexes from disk. |
102 |
*/ |
103 |
*/ |
103 |
public void cleanUpIndexes() { |
104 |
public void cleanUpIndexes() { |
104 |
SimpleLookupTable knownPaths = new SimpleLookupTable(); |
105 |
SimpleSet knownPaths = new SimpleSet(); |
105 |
IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope(); |
106 |
IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope(); |
106 |
PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null); |
107 |
PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null); |
107 |
Index[] selectedIndexes = job.getIndexes(null); |
108 |
Index[] selectedIndexes = job.getIndexes(null); |
108 |
for (int j = 0, max = selectedIndexes.length; j < max; j++) { |
109 |
for (int i = 0, l = selectedIndexes.length; i < l; i++) { |
109 |
// TODO should use getJavaPluginWorkingLocation()+index simple name to avoid bugs such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267 |
110 |
String path = selectedIndexes[i].getIndexFile().getAbsolutePath(); |
110 |
String path = selectedIndexes[j].getIndexFile().getAbsolutePath(); |
111 |
knownPaths.add(path); |
111 |
knownPaths.put(path, path); |
|
|
112 |
} |
112 |
} |
113 |
|
113 |
|
114 |
if (indexStates != null) { |
114 |
if (this.indexStates != null) { |
115 |
Object[] keys = indexStates.keyTable; |
115 |
Object[] keys = this.indexStates.keyTable; |
116 |
int keysLength = keys.length; |
116 |
IPath[] locations = new IPath[this.indexStates.elementSize]; |
117 |
int updates = 0; |
117 |
int count = 0; |
118 |
String locations[] = new String[keysLength]; |
|
|
119 |
for (int i = 0, l = keys.length; i < l; i++) { |
118 |
for (int i = 0, l = keys.length; i < l; i++) { |
120 |
String key = (String) keys[i]; |
119 |
IPath key = (IPath) keys[i]; |
121 |
if (key != null && !knownPaths.containsKey(key)) { |
120 |
if (key != null && !knownPaths.includes(key.toOSString())) |
122 |
locations[updates++] = key; |
121 |
locations[count++] = key; |
123 |
} |
|
|
124 |
} |
122 |
} |
125 |
if (updates > 0) { |
123 |
if (count > 0) |
126 |
removeIndexesState(locations); |
124 |
removeIndexesState(locations); |
127 |
} |
|
|
128 |
} |
129 |
|
130 |
File indexesDirectory = new File(getJavaPluginWorkingLocation().toOSString()); |
131 |
if (indexesDirectory.isDirectory()) { |
132 |
File[] indexesFiles = indexesDirectory.listFiles(); |
133 |
if (indexesFiles != null) { |
134 |
for (int i = 0, indexesFilesLength = indexesFiles.length; i < indexesFilesLength; i++) { |
135 |
String fileName = indexesFiles[i].getAbsolutePath(); |
136 |
if (!knownPaths.containsKey(fileName) && fileName.toLowerCase().endsWith(".index")) { //$NON-NLS-1$ |
137 |
if (VERBOSE) |
138 |
Util.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$ |
139 |
indexesFiles[i].delete(); |
140 |
} |
141 |
} |
142 |
} |
143 |
} |
125 |
} |
|
|
126 |
deleteIndexFiles(knownPaths); |
144 |
} |
127 |
} |
145 |
public String computeIndexLocation(IPath containerPath) { |
128 |
public IPath computeIndexLocation(IPath containerPath) { |
146 |
String indexLocation = (String) this.indexLocations.get(containerPath); |
129 |
IPath indexLocation = (IPath) this.indexLocations.get(containerPath); |
147 |
if (indexLocation == null) { |
130 |
if (indexLocation == null) { |
148 |
String pathString = containerPath.toOSString(); |
131 |
String pathString = containerPath.toOSString(); |
149 |
checksumCalculator.reset(); |
132 |
checksumCalculator.reset(); |
Lines 151-165
Link Here
|
151 |
String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$ |
134 |
String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$ |
152 |
if (VERBOSE) |
135 |
if (VERBOSE) |
153 |
Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$ |
136 |
Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$ |
154 |
indexLocation = getJavaPluginWorkingLocation().append(fileName).toOSString(); |
137 |
// to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table |
|
|
138 |
indexLocation = (IPath) getIndexStates().getKey(getJavaPluginWorkingLocation().append(fileName)); |
155 |
this.indexLocations.put(containerPath, indexLocation); |
139 |
this.indexLocations.put(containerPath, indexLocation); |
156 |
} |
140 |
} |
157 |
return indexLocation; |
141 |
return indexLocation; |
158 |
} |
142 |
} |
|
|
143 |
private void deleteIndexFiles(SimpleSet pathsToKeep) { |
144 |
File[] indexesFiles = getSavedIndexesDirectory().listFiles(); |
145 |
if (indexesFiles == null) return; |
146 |
|
147 |
for (int i = 0, l = indexesFiles.length; i < l; i++) { |
148 |
String fileName = indexesFiles[i].getAbsolutePath(); |
149 |
if (pathsToKeep != null && pathsToKeep.includes(fileName)) continue; |
150 |
String suffix = ".index"; //$NON-NLS-1$ |
151 |
if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) { |
152 |
if (VERBOSE) |
153 |
Util.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$ |
154 |
indexesFiles[i].delete(); |
155 |
} |
156 |
} |
157 |
} |
159 |
/* |
158 |
/* |
160 |
* Creates an empty index at the given location, for the given container path, if none exist. |
159 |
* Creates an empty index at the given location, for the given container path, if none exist. |
161 |
*/ |
160 |
*/ |
162 |
public void ensureIndexExists(String indexLocation, IPath containerPath) { |
161 |
public void ensureIndexExists(IPath indexLocation, IPath containerPath) { |
163 |
SimpleLookupTable states = getIndexStates(); |
162 |
SimpleLookupTable states = getIndexStates(); |
164 |
Object state = states.get(indexLocation); |
163 |
Object state = states.get(indexLocation); |
165 |
if (state == null) { |
164 |
if (state == null) { |
Lines 196-202
Link Here
|
196 |
* Warning: Does not check whether index is consistent (not being used) |
195 |
* Warning: Does not check whether index is consistent (not being used) |
197 |
*/ |
196 |
*/ |
198 |
public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { |
197 |
public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { |
199 |
String indexLocation = computeIndexLocation(containerPath); |
198 |
IPath indexLocation = computeIndexLocation(containerPath); |
200 |
return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); |
199 |
return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); |
201 |
} |
200 |
} |
202 |
/** |
201 |
/** |
Lines 207-215
Link Here
|
207 |
* |
206 |
* |
208 |
* Warning: Does not check whether index is consistent (not being used) |
207 |
* Warning: Does not check whether index is consistent (not being used) |
209 |
*/ |
208 |
*/ |
210 |
public synchronized Index getIndex(IPath containerPath, String indexLocation, boolean reuseExistingFile, boolean createIfMissing) { |
209 |
public synchronized Index getIndex(IPath containerPath, IPath indexLocation, boolean reuseExistingFile, boolean createIfMissing) { |
211 |
// Path is already canonical per construction |
210 |
// Path is already canonical per construction |
212 |
Index index = (Index) indexes.get(indexLocation); |
211 |
Index index = getIndex(indexLocation); |
213 |
if (index == null) { |
212 |
if (index == null) { |
214 |
Object state = getIndexStates().get(indexLocation); |
213 |
Object state = getIndexStates().get(indexLocation); |
215 |
Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; |
214 |
Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; |
Lines 222-239
Link Here
|
222 |
|
221 |
|
223 |
// index isn't cached, consider reusing an existing index file |
222 |
// index isn't cached, consider reusing an existing index file |
224 |
String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); |
223 |
String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); |
|
|
224 |
String indexLocationString = indexLocation.toOSString(); |
225 |
if (reuseExistingFile) { |
225 |
if (reuseExistingFile) { |
226 |
File indexFile = new File(indexLocation); |
226 |
File indexFile = new File(indexLocationString); |
227 |
if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing |
227 |
if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing |
228 |
try { |
228 |
try { |
229 |
index = new Index(indexLocation, containerPathString, true /*reuse index file*/); |
229 |
index = new Index(indexLocationString, containerPathString, true /*reuse index file*/); |
230 |
indexes.put(indexLocation, index); |
230 |
this.indexes.put(indexLocation, index); |
231 |
return index; |
231 |
return index; |
232 |
} catch (IOException e) { |
232 |
} catch (IOException e) { |
233 |
// failed to read the existing file or its no longer compatible |
233 |
// failed to read the existing file or its no longer compatible |
234 |
if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt |
234 |
if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt |
235 |
if (VERBOSE) |
235 |
if (VERBOSE) |
236 |
Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
236 |
Util.verbose("-> cannot reuse existing index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
237 |
rebuildIndex(indexLocation, containerPath); |
237 |
rebuildIndex(indexLocation, containerPath); |
238 |
return null; |
238 |
return null; |
239 |
} |
239 |
} |
Lines 249-261
Link Here
|
249 |
if (createIfMissing) { |
249 |
if (createIfMissing) { |
250 |
try { |
250 |
try { |
251 |
if (VERBOSE) |
251 |
if (VERBOSE) |
252 |
Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
252 |
Util.verbose("-> create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
253 |
index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); |
253 |
index = new Index(indexLocationString, containerPathString, false /*do not reuse index file*/); |
254 |
indexes.put(indexLocation, index); |
254 |
this.indexes.put(indexLocation, index); |
255 |
return index; |
255 |
return index; |
256 |
} catch (IOException e) { |
256 |
} catch (IOException e) { |
257 |
if (VERBOSE) |
257 |
if (VERBOSE) |
258 |
Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
258 |
Util.verbose("-> unable to create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
259 |
// The file could not be created. Possible reason: the project has been deleted. |
259 |
// The file could not be created. Possible reason: the project has been deleted. |
260 |
return null; |
260 |
return null; |
261 |
} |
261 |
} |
Lines 264-312
Link Here
|
264 |
//System.out.println(" index name: " + path.toOSString() + " <----> " + index.getIndexFile().getName()); |
264 |
//System.out.println(" index name: " + path.toOSString() + " <----> " + index.getIndexFile().getName()); |
265 |
return index; |
265 |
return index; |
266 |
} |
266 |
} |
267 |
public synchronized Index getIndex(String indexLocation) { |
267 |
public synchronized Index getIndex(IPath indexLocation) { |
268 |
return (Index) indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed |
268 |
return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed |
269 |
} |
269 |
} |
270 |
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { |
270 |
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { |
271 |
String indexLocation = computeIndexLocation(containerPath); |
271 |
IPath indexLocation = computeIndexLocation(containerPath); |
272 |
if (getIndexStates().get(indexLocation) == REBUILDING_STATE) |
272 |
if (getIndexStates().get(indexLocation) == REBUILDING_STATE) |
273 |
return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); |
273 |
return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); |
274 |
|
274 |
|
275 |
return null; // abort the job since the index has been removed from the REBUILDING_STATE |
275 |
return null; // abort the job since the index has been removed from the REBUILDING_STATE |
276 |
} |
276 |
} |
277 |
private SimpleLookupTable getIndexStates() { |
277 |
private SimpleLookupTable getIndexStates() { |
278 |
if (indexStates != null) return indexStates; |
278 |
if (this.indexStates != null) return this.indexStates; |
279 |
|
279 |
|
280 |
this.indexStates = new SimpleLookupTable(); |
280 |
this.indexStates = new SimpleLookupTable(); |
281 |
char[] savedIndexNames = readIndexState(); |
281 |
IPath indexesDirectoryPath = getJavaPluginWorkingLocation(); |
282 |
if (savedIndexNames.length > 0) { |
282 |
char[][] savedNames = readIndexState(indexesDirectoryPath.toOSString()); |
283 |
char[][] names = CharOperation.splitOn('\n', savedIndexNames); |
283 |
if (savedNames != null) { |
284 |
if (names.length > 0) { |
284 |
for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState() |
285 |
// check to see if workspace has moved, if so then do not trust saved indexes |
285 |
char[] savedName = savedNames[i]; |
286 |
File indexesDirectory = new File(getJavaPluginWorkingLocation().toOSString()); |
286 |
if (savedName.length > 0) { |
287 |
char[] dirName = indexesDirectory.getAbsolutePath().toCharArray(); |
287 |
IPath indexLocation = indexesDirectoryPath.append(new String(savedName)); // shares indexesDirectoryPath's segments |
288 |
int delimiterPos = dirName.length; |
288 |
if (VERBOSE) |
289 |
if (CharOperation.match(names[0], 0, delimiterPos, dirName, 0, delimiterPos, true)) { |
289 |
Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$ |
290 |
for (int i = 0, l = names.length; i < l; i++) { |
290 |
this.indexStates.put(indexLocation, SAVED_STATE); |
291 |
char[] name = names[i]; |
|
|
292 |
if (name.length > 0) |
293 |
this.indexStates.put(new String(name), SAVED_STATE); |
294 |
} |
295 |
} else { |
296 |
savedIndexNamesFile.delete(); // forget saved indexes & delete each index file |
297 |
File[] files = indexesDirectory.listFiles(); |
298 |
if (files != null) { |
299 |
for (int i = 0, l = files.length; i < l; i++) { |
300 |
String fileName = files[i].getAbsolutePath(); |
301 |
if (fileName.toLowerCase().endsWith(".index")) { //$NON-NLS-1$ |
302 |
if (VERBOSE) |
303 |
Util.verbose("Deleting index file " + files[i]); //$NON-NLS-1$ |
304 |
files[i].delete(); |
305 |
} |
306 |
} |
307 |
} |
308 |
} |
291 |
} |
309 |
} |
292 |
} |
|
|
293 |
} else { |
294 |
this.savedIndexNamesFile.delete(); // forget saved indexes & delete each index file |
295 |
deleteIndexFiles(null); |
310 |
} |
296 |
} |
311 |
return this.indexStates; |
297 |
return this.indexStates; |
312 |
} |
298 |
} |
Lines 316-321
Link Here
|
316 |
IPath stateLocation = JavaCore.getPlugin().getStateLocation(); |
302 |
IPath stateLocation = JavaCore.getPlugin().getStateLocation(); |
317 |
return this.javaPluginLocation = stateLocation; |
303 |
return this.javaPluginLocation = stateLocation; |
318 |
} |
304 |
} |
|
|
305 |
private File getSavedIndexesDirectory() { |
306 |
return new File(getJavaPluginWorkingLocation().toOSString()); |
307 |
} |
319 |
public void indexDocument(SearchDocument searchDocument, SearchParticipant searchParticipant, Index index, IPath indexLocation) { |
308 |
public void indexDocument(SearchDocument searchDocument, SearchParticipant searchParticipant, Index index, IPath indexLocation) { |
320 |
try { |
309 |
try { |
321 |
((InternalSearchDocument) searchDocument).index = index; |
310 |
((InternalSearchDocument) searchDocument).index = index; |
Lines 365-372
Link Here
|
365 |
IndexRequest request = null; |
354 |
IndexRequest request = null; |
366 |
if (target instanceof IFile) { |
355 |
if (target instanceof IFile) { |
367 |
request = new AddJarFileToIndex((IFile) target, this); |
356 |
request = new AddJarFileToIndex((IFile) target, this); |
368 |
} else if (target instanceof java.io.File) { |
357 |
} else if (target instanceof File) { |
369 |
if (((java.io.File) target).isFile()) { |
358 |
if (((File) target).isFile()) { |
370 |
request = new AddJarFileToIndex(path, this); |
359 |
request = new AddJarFileToIndex(path, this); |
371 |
} else { |
360 |
} else { |
372 |
return; |
361 |
return; |
Lines 394-405
Link Here
|
394 |
|
383 |
|
395 |
this.request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this)); |
384 |
this.request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this)); |
396 |
} |
385 |
} |
397 |
public void jobWasCancelled(IPath containerPath) { |
386 |
public synchronized void jobWasCancelled(IPath containerPath) { |
398 |
String indexLocation = computeIndexLocation(containerPath); |
387 |
IPath indexLocation = computeIndexLocation(containerPath); |
399 |
Object o = this.indexes.get(indexLocation); |
388 |
Index index = getIndex(indexLocation); |
400 |
if (o instanceof Index) { |
389 |
if (index != null) { |
401 |
((Index) o).monitor = null; |
390 |
index.monitor = null; |
402 |
this.indexes.remove(indexLocation); |
391 |
this.indexes.removeKey(indexLocation); |
403 |
} |
392 |
} |
404 |
updateIndexState(indexLocation, UNKNOWN_STATE); |
393 |
updateIndexState(indexLocation, UNKNOWN_STATE); |
405 |
} |
394 |
} |
Lines 424-437
Link Here
|
424 |
public String processName(){ |
413 |
public String processName(){ |
425 |
return Messages.process_name; |
414 |
return Messages.process_name; |
426 |
} |
415 |
} |
427 |
private void rebuildIndex(String indexLocation, IPath containerPath) { |
416 |
private void rebuildIndex(IPath indexLocation, IPath containerPath) { |
428 |
IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
417 |
IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
429 |
if (workspace == null) return; |
418 |
if (workspace == null) return; |
430 |
Object target = JavaModel.getTarget(workspace.getRoot(), containerPath, true); |
419 |
Object target = JavaModel.getTarget(workspace.getRoot(), containerPath, true); |
431 |
if (target == null) return; |
420 |
if (target == null) return; |
432 |
|
421 |
|
433 |
if (VERBOSE) |
422 |
if (VERBOSE) |
434 |
Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$ |
423 |
Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath); //$NON-NLS-1$ //$NON-NLS-2$ |
435 |
|
424 |
|
436 |
updateIndexState(indexLocation, REBUILDING_STATE); |
425 |
updateIndexState(indexLocation, REBUILDING_STATE); |
437 |
IndexRequest request = null; |
426 |
IndexRequest request = null; |
Lines 443-449
Link Here
|
443 |
request = new IndexBinaryFolder((IFolder) target, this); |
432 |
request = new IndexBinaryFolder((IFolder) target, this); |
444 |
} else if (target instanceof IFile) { |
433 |
} else if (target instanceof IFile) { |
445 |
request = new AddJarFileToIndex((IFile) target, this); |
434 |
request = new AddJarFileToIndex((IFile) target, this); |
446 |
} else if (target instanceof java.io.File) { |
435 |
} else if (target instanceof File) { |
447 |
request = new AddJarFileToIndex(containerPath, this); |
436 |
request = new AddJarFileToIndex(containerPath, this); |
448 |
} |
437 |
} |
449 |
if (request != null) |
438 |
if (request != null) |
Lines 459-472
Link Here
|
459 |
String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); |
448 |
String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); |
460 |
try { |
449 |
try { |
461 |
// Path is already canonical |
450 |
// Path is already canonical |
462 |
String indexLocation = computeIndexLocation(containerPath); |
451 |
IPath indexLocation = computeIndexLocation(containerPath); |
463 |
|
452 |
Index index = getIndex(indexLocation); |
464 |
Index index = (Index) this.indexes.get(indexLocation); |
|
|
465 |
ReadWriteMonitor monitor = index == null ? null : index.monitor; |
453 |
ReadWriteMonitor monitor = index == null ? null : index.monitor; |
466 |
|
454 |
|
467 |
if (VERBOSE) |
455 |
if (VERBOSE) |
468 |
Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
456 |
Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ |
469 |
index = new Index(indexLocation, containerPathString, false /*reuse index file*/); |
457 |
index = new Index(indexLocation.toOSString(), containerPathString, false /*reuse index file*/); |
470 |
this.indexes.put(indexLocation, index); |
458 |
this.indexes.put(indexLocation, index); |
471 |
index.monitor = monitor; |
459 |
index.monitor = monitor; |
472 |
return index; |
460 |
return index; |
Lines 493-538
Link Here
|
493 |
public synchronized void removeIndex(IPath containerPath) { |
481 |
public synchronized void removeIndex(IPath containerPath) { |
494 |
if (VERBOSE) |
482 |
if (VERBOSE) |
495 |
Util.verbose("removing index " + containerPath); //$NON-NLS-1$ |
483 |
Util.verbose("removing index " + containerPath); //$NON-NLS-1$ |
496 |
String indexLocation = computeIndexLocation(containerPath); |
484 |
IPath indexLocation = computeIndexLocation(containerPath); |
497 |
File indexFile = new File(indexLocation); |
485 |
Index index = getIndex(indexLocation); |
|
|
486 |
File indexFile = null; |
487 |
if (index != null) { |
488 |
index.monitor = null; |
489 |
indexFile = index.getIndexFile(); |
490 |
} |
491 |
if (indexFile == null) |
492 |
indexFile = new File(indexLocation.toOSString()); // index is not cached yet, but still want to delete the file |
498 |
if (indexFile.exists()) |
493 |
if (indexFile.exists()) |
499 |
indexFile.delete(); |
494 |
indexFile.delete(); |
500 |
Object o = this.indexes.get(indexLocation); |
495 |
this.indexes.removeKey(indexLocation); |
501 |
if (o instanceof Index) |
|
|
502 |
((Index) o).monitor = null; |
503 |
this.indexes.remove(indexLocation); |
504 |
updateIndexState(indexLocation, null); |
496 |
updateIndexState(indexLocation, null); |
505 |
} |
497 |
} |
506 |
/** |
498 |
/** |
507 |
* Removes all indexes whose paths start with (or are equal to) the given path. |
499 |
* Removes all indexes whose paths start with (or are equal to) the given path. |
508 |
*/ |
500 |
*/ |
509 |
public synchronized void removeIndexPath(IPath path) { |
501 |
public synchronized void removeIndexPath(IPath path) { |
510 |
Set entrySet = this.indexes.entrySet(); |
502 |
Object[] keyTable = this.indexes.keyTable; |
511 |
Iterator entries = entrySet.iterator(); |
503 |
Object[] valueTable = this.indexes.valueTable; |
512 |
String[] locations = null; |
504 |
IPath[] locations = null; |
513 |
int max = entrySet.size(); |
505 |
int max = this.indexes.elementSize; |
514 |
int ptr = 0; |
506 |
int count = 0; |
515 |
while (entries.hasNext()) { |
507 |
for (int i = 0, l = keyTable.length; i < l; i++) { |
516 |
Map.Entry entry = (Map.Entry) entries.next(); |
508 |
IPath indexLocation = (IPath) keyTable[i]; |
517 |
String indexLocation = (String) entry.getKey(); |
509 |
if (indexLocation == null) |
518 |
IPath indexPath = new Path(indexLocation); |
510 |
continue; |
519 |
if (path.isPrefixOf(indexPath)) { |
511 |
if (path.isPrefixOf(indexLocation)) { |
520 |
Index index = (Index) entry.getValue(); |
512 |
Index index = (Index) valueTable[i]; |
521 |
if (index != null) index.monitor = null; |
513 |
index.monitor = null; |
522 |
if (locations == null) locations = new String[max]; |
514 |
if (locations == null) |
523 |
locations[ptr++] = indexLocation; |
515 |
locations = new IPath[max]; |
524 |
File indexFile = new File(indexLocation); |
516 |
locations[count++] = indexLocation; |
525 |
if (indexFile.exists()) { |
517 |
File indexFile = index.getIndexFile(); |
|
|
518 |
if (indexFile.exists()) |
526 |
indexFile.delete(); |
519 |
indexFile.delete(); |
527 |
} |
520 |
} else { |
528 |
} else if (locations == null) { |
|
|
529 |
max--; |
521 |
max--; |
530 |
} |
522 |
} |
531 |
} |
523 |
} |
532 |
if (locations != null) { |
524 |
if (locations != null) { |
533 |
for (int i=0; i<ptr; i++) { |
525 |
for (int i = 0; i < count; i++) |
534 |
this.indexes.remove(locations[i]); |
526 |
this.indexes.removeKey(locations[i]); |
535 |
} |
|
|
536 |
removeIndexesState(locations); |
527 |
removeIndexesState(locations); |
537 |
} |
528 |
} |
538 |
} |
529 |
} |
Lines 575-581
Link Here
|
575 |
public synchronized void reset() { |
566 |
public synchronized void reset() { |
576 |
super.reset(); |
567 |
super.reset(); |
577 |
if (this.indexes != null) { |
568 |
if (this.indexes != null) { |
578 |
this.indexes = new HashMap(5); |
569 |
this.indexes = new SimpleLookupTable(); |
579 |
this.indexStates = null; |
570 |
this.indexStates = null; |
580 |
} |
571 |
} |
581 |
this.indexLocations = new SimpleLookupTable(); |
572 |
this.indexLocations = new SimpleLookupTable(); |
Lines 588-608
Link Here
|
588 |
Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$ |
579 |
Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$ |
589 |
index.save(); |
580 |
index.save(); |
590 |
} |
581 |
} |
591 |
// TODO should use getJavaPluginWorkingLocation()+index simple name to avoid bugs such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267 |
582 |
synchronized (this) { |
592 |
String indexLocation = index.getIndexFile().getPath(); |
583 |
IPath containerPath = new Path(index.containerPath); |
593 |
if (this.jobEnd > this.jobStart) { |
584 |
if (this.jobEnd > this.jobStart) { |
594 |
Object containerPath = this.indexLocations.keyForValue(indexLocation); |
585 |
for (int i = this.jobEnd; i > this.jobStart; i--) { // skip the current job |
595 |
if (containerPath != null) { |
586 |
IJob job = this.awaitingJobs[i]; |
596 |
synchronized(this) { |
587 |
if (job instanceof IndexRequest) |
597 |
for (int i = this.jobEnd; i > this.jobStart; i--) { // skip the current job |
588 |
if (((IndexRequest) job).containerPath.equals(containerPath)) return; |
598 |
IJob job = this.awaitingJobs[i]; |
|
|
599 |
if (job instanceof IndexRequest) |
600 |
if (((IndexRequest) job).containerPath.equals(containerPath)) return; |
601 |
} |
602 |
} |
589 |
} |
603 |
} |
590 |
} |
|
|
591 |
IPath indexLocation = computeIndexLocation(containerPath); |
592 |
updateIndexState(indexLocation, SAVED_STATE); |
604 |
} |
593 |
} |
605 |
updateIndexState(indexLocation, SAVED_STATE); |
|
|
606 |
} |
594 |
} |
607 |
/** |
595 |
/** |
608 |
* Commit all index memory changes to disk |
596 |
* Commit all index memory changes to disk |
Lines 611-620
Link Here
|
611 |
// only save cached indexes... the rest were not modified |
599 |
// only save cached indexes... the rest were not modified |
612 |
ArrayList toSave = new ArrayList(); |
600 |
ArrayList toSave = new ArrayList(); |
613 |
synchronized(this) { |
601 |
synchronized(this) { |
614 |
for (Iterator iter = this.indexes.values().iterator(); iter.hasNext();) { |
602 |
Object[] valueTable = this.indexes.valueTable; |
615 |
Object o = iter.next(); |
603 |
for (int i = 0, l = valueTable.length; i < l; i++) { |
616 |
if (o instanceof Index) |
604 |
Index index = (Index) valueTable[i]; |
617 |
toSave.add(o); |
605 |
if (index != null) |
|
|
606 |
toSave.add(index); |
618 |
} |
607 |
} |
619 |
} |
608 |
} |
620 |
|
609 |
|
Lines 650-656
Link Here
|
650 |
} |
639 |
} |
651 |
this.needToSave = !allSaved; |
640 |
this.needToSave = !allSaved; |
652 |
} |
641 |
} |
653 |
public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final String indexLocation, final SearchParticipant searchParticipant) { |
642 |
public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IPath indexLocation, final SearchParticipant searchParticipant) { |
654 |
request(new IndexRequest(container, this) { |
643 |
request(new IndexRequest(container, this) { |
655 |
public boolean execute(IProgressMonitor progressMonitor) { |
644 |
public boolean execute(IProgressMonitor progressMonitor) { |
656 |
if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; |
645 |
if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; |
Lines 663-669
Link Here
|
663 |
|
652 |
|
664 |
try { |
653 |
try { |
665 |
monitor.enterWrite(); // ask permission to write |
654 |
monitor.enterWrite(); // ask permission to write |
666 |
indexDocument(searchDocument, searchParticipant, index, new Path(indexLocation)); |
655 |
indexDocument(searchDocument, searchParticipant, index, indexLocation); |
667 |
} finally { |
656 |
} finally { |
668 |
monitor.exitWrite(); // free write lock |
657 |
monitor.exitWrite(); // free write lock |
669 |
} |
658 |
} |
Lines 680-701
Link Here
|
680 |
buffer.append(super.toString()); |
669 |
buffer.append(super.toString()); |
681 |
buffer.append("In-memory indexes:\n"); //$NON-NLS-1$ |
670 |
buffer.append("In-memory indexes:\n"); //$NON-NLS-1$ |
682 |
int count = 0; |
671 |
int count = 0; |
683 |
for (Iterator iter = this.indexes.values().iterator(); iter.hasNext();) { |
672 |
Object[] valueTable = this.indexes.valueTable; |
684 |
buffer.append(++count).append(" - ").append(iter.next().toString()).append('\n'); //$NON-NLS-1$ |
673 |
for (int i = 0, l = valueTable.length; i < l; i++) { |
|
|
674 |
Index index = (Index) valueTable[i]; |
675 |
if (index != null) |
676 |
buffer.append(++count).append(" - ").append(index.toString()).append('\n'); //$NON-NLS-1$ |
685 |
} |
677 |
} |
686 |
return buffer.toString(); |
678 |
return buffer.toString(); |
687 |
} |
679 |
} |
688 |
|
680 |
|
689 |
private char[] readIndexState() { |
681 |
private char[][] readIndexState(String dirOSString) { |
690 |
try { |
682 |
try { |
691 |
return org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(savedIndexNamesFile, null); |
683 |
char[] savedIndexNames = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(savedIndexNamesFile, null); |
|
|
684 |
if (savedIndexNames.length > 0) { |
685 |
char[][] names = CharOperation.splitOn('\n', savedIndexNames); |
686 |
if (names.length > 1) { |
687 |
// First line is DiskIndex signature + saved plugin working location (see writeSavedIndexNamesFile()) |
688 |
String savedSignature = DiskIndex.SIGNATURE + "+" + dirOSString; //$NON-NLS-1$ |
689 |
if (savedSignature.equals(new String(names[0]))) |
690 |
return names; |
691 |
} |
692 |
} |
692 |
} catch (IOException ignored) { |
693 |
} catch (IOException ignored) { |
693 |
if (VERBOSE) |
694 |
if (VERBOSE) |
694 |
Util.verbose("Failed to read saved index file names"); //$NON-NLS-1$ |
695 |
Util.verbose("Failed to read saved index file names"); //$NON-NLS-1$ |
695 |
return CharOperation.NO_CHAR; |
|
|
696 |
} |
696 |
} |
|
|
697 |
return null; |
697 |
} |
698 |
} |
698 |
private synchronized void removeIndexesState(String[] locations) { |
699 |
private synchronized void removeIndexesState(IPath[] locations) { |
699 |
getIndexStates(); // ensure the states are initialized |
700 |
getIndexStates(); // ensure the states are initialized |
700 |
int length = locations.length; |
701 |
int length = locations.length; |
701 |
boolean changed = false; |
702 |
boolean changed = false; |
Lines 712-718
Link Here
|
712 |
|
713 |
|
713 |
writeSavedIndexNamesFile(); |
714 |
writeSavedIndexNamesFile(); |
714 |
} |
715 |
} |
715 |
private synchronized void updateIndexState(String indexLocation, Integer indexState) { |
716 |
private synchronized void updateIndexState(IPath indexLocation, Integer indexState) { |
716 |
getIndexStates(); // ensure the states are initialized |
717 |
getIndexStates(); // ensure the states are initialized |
717 |
if (indexState != null) { |
718 |
if (indexState != null) { |
718 |
if (indexState.equals(indexStates.get(indexLocation))) return; // not changed |
719 |
if (indexState.equals(indexStates.get(indexLocation))) return; // not changed |
Lines 737-747
Link Here
|
737 |
BufferedWriter writer = null; |
738 |
BufferedWriter writer = null; |
738 |
try { |
739 |
try { |
739 |
writer = new BufferedWriter(new FileWriter(savedIndexNamesFile)); |
740 |
writer = new BufferedWriter(new FileWriter(savedIndexNamesFile)); |
|
|
741 |
writer.write(DiskIndex.SIGNATURE); |
742 |
writer.write('+'); |
743 |
writer.write(getJavaPluginWorkingLocation().toOSString()); |
744 |
writer.write('\n'); |
740 |
Object[] keys = indexStates.keyTable; |
745 |
Object[] keys = indexStates.keyTable; |
741 |
Object[] states = indexStates.valueTable; |
746 |
Object[] states = indexStates.valueTable; |
742 |
for (int i = 0, l = states.length; i < l; i++) { |
747 |
for (int i = 0, l = states.length; i < l; i++) { |
743 |
if (states[i] == SAVED_STATE) { |
748 |
if (states[i] == SAVED_STATE) { |
744 |
writer.write((String) keys[i]); |
749 |
writer.write(((IPath) keys[i]).lastSegment()); |
745 |
writer.write('\n'); |
750 |
writer.write('\n'); |
746 |
} |
751 |
} |
747 |
} |
752 |
} |