blob: fea16f188b9251ba369063cdff4394b05d830d2c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.internal.core.search;
import java.io.IOException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.SearchParticipant;
import org.eclipse.dltk.core.search.SearchPattern;
import org.eclipse.dltk.core.search.index.Index;
import org.eclipse.dltk.core.search.indexing.IndexManager;
import org.eclipse.dltk.core.search.indexing.ReadWriteMonitor;
import org.eclipse.dltk.core.search.matching.MatchLocator;
import org.eclipse.dltk.internal.core.ModelManager;
import org.eclipse.dltk.internal.core.search.processing.IJob;
import org.eclipse.dltk.internal.core.search.processing.JobManager;
public class PatternSearchJob implements IJob {
protected SearchPattern pattern;
protected IDLTKSearchScope scope;
protected SearchParticipant participant;
protected IndexQueryRequestor requestor;
protected boolean areIndexesReady;
protected long executionTime = 0;
public PatternSearchJob(SearchPattern pattern,
SearchParticipant participant, IDLTKSearchScope scope,
IndexQueryRequestor requestor) {
this.pattern = pattern;
this.participant = participant;
this.scope = scope;
this.requestor = requestor;
}
@Override
public boolean belongsTo(String jobFamily) {
return true;
}
@Override
public void cancel() {
// search job is cancelled through progress
}
@Override
public void ensureReadyToRun() {
if (!this.areIndexesReady)
getIndexes(null/* progress */); // may trigger some index recreation
}
@Override
public boolean execute(IProgressMonitor progressMonitor) {
if (progressMonitor != null && progressMonitor.isCanceled())
throw new OperationCanceledException();
boolean isComplete = COMPLETE;
executionTime = 0;
Index[] indexes = getIndexes(progressMonitor);
try {
int max = indexes.length;
if (progressMonitor != null)
progressMonitor.beginTask("", max); //$NON-NLS-1$
for (int i = 0; i < max; i++) {
isComplete &= search(indexes[i], progressMonitor);
if (progressMonitor != null) {
if (progressMonitor.isCanceled())
throw new OperationCanceledException();
progressMonitor.worked(1);
}
}
if (JobManager.VERBOSE)
System.err.println("-> execution time: " + executionTime + "ms - " + this);//$NON-NLS-1$//$NON-NLS-2$
return isComplete;
} finally {
if (progressMonitor != null)
progressMonitor.done();
}
}
public Index[] getIndexes(IProgressMonitor progressMonitor) {
// acquire the in-memory indexes on the fly
IPath[] indexLocations = this.participant.selectIndexes(this.pattern,
this.scope);
int length = indexLocations.length;
Index[] indexes = new Index[length];
int count = 0;
IndexManager indexManager = ModelManager.getModelManager()
.getIndexManager();
for (int i = 0; i < length; i++) {
if (progressMonitor != null && progressMonitor.isCanceled())
throw new OperationCanceledException();
// may trigger some index recreation work
String indexLocation = indexLocations[i].toOSString();
Index index = indexManager.getIndex(indexLocation);
if (index == null) {
// only need containerPath if the index must be built
IPath containerPath = (IPath) indexManager.indexLocations
.keyForValue(indexLocation);
if (containerPath != null) // sanity check
index = indexManager
.getIndex(containerPath, indexLocation,
true /* reuse index file */, false /*
* do
* not
* create
* if
* none
*/);
}
if (index != null) {
// index.setDiskIndexCaching(this.pattern instanceof MixinPattern);
indexes[count++] = index; // only consider indexes which are
// ready
}
}
if (count == length)
this.areIndexesReady = true;
else
System.arraycopy(indexes, 0, indexes = new Index[count], 0, count);
return indexes;
}
public boolean search(Index index, IProgressMonitor progressMonitor) {
if (index == null)
return COMPLETE;
if (progressMonitor != null && progressMonitor.isCanceled())
throw new OperationCanceledException();
ReadWriteMonitor monitor = index.monitor;
if (monitor == null)
return COMPLETE; // index got deleted since acquired
try {
monitor.enterRead(); // ask permission to read
long start = System.currentTimeMillis();
MatchLocator.findIndexMatches(this.pattern, index, requestor,
this.participant, this.scope, progressMonitor);
executionTime += System.currentTimeMillis() - start;
return COMPLETE;
} catch (IOException e) {
if (e instanceof java.io.EOFException)
e.printStackTrace();
return FAILED;
} finally {
monitor.exitRead(); // finished reading
}
}
@Override
public String toString() {
return "searching " + pattern.toString(); //$NON-NLS-1$
}
}