diff --git a/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java b/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java --- a/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java +++ b/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java @@ -181,10 +181,7 @@ import org.netbeans.modules.parsing.api.Snapshot; import org.netbeans.modules.parsing.api.Source; import org.netbeans.modules.parsing.api.UserTask; -import org.netbeans.modules.parsing.impl.indexing.CacheFolder; -import org.netbeans.modules.parsing.impl.indexing.FileObjectIndexable; -import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater; -import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +import org.netbeans.modules.parsing.impl.indexing.*; import org.netbeans.modules.parsing.impl.indexing.lucene.LayeredDocumentIndex; import org.netbeans.modules.parsing.impl.indexing.lucene.LuceneIndexFactory; import org.netbeans.modules.parsing.impl.indexing.lucene.TestIndexFactoryImpl; @@ -1562,6 +1559,8 @@ false, false, false, + SuspendSupport.NOP, + null, null ); diff --git a/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java b/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java --- a/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java +++ b/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java @@ -108,6 +108,7 @@ import org.netbeans.modules.java.source.parsing.FileObjects; import org.netbeans.modules.java.source.usages.ClassIndexImpl.UsageType; import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +import org.netbeans.modules.parsing.impl.indexing.SuspendSupport; import org.netbeans.modules.parsing.lucene.support.LowMemoryWatcher; import org.netbeans.modules.parsing.spi.indexing.Context; import org.openide.filesystems.FileObject; @@ -200,8 +201,20 @@ */ @Deprecated public final Result start (final @NonNull URL url, final AtomicBoolean canceled, final AtomicBoolean shutdown) throws IOException, IllegalArgumentException { - return start (url, SPIAccessor.getInstance().createContext(FileUtil.createMemoryFileSystem().getRoot(), url, - JavaIndex.NAME, JavaIndex.VERSION, null, false, false, false, null)); + return start ( + url, + SPIAccessor.getInstance().createContext( + FileUtil.createMemoryFileSystem().getRoot(), + url, + JavaIndex.NAME, + JavaIndex.VERSION, + null, + false, + false, + false, + SuspendSupport.NOP, + null, + null)); } public Result resume () throws IOException { diff --git a/parsing.api/apichanges.xml b/parsing.api/apichanges.xml --- a/parsing.api/apichanges.xml +++ b/parsing.api/apichanges.xml @@ -110,6 +110,25 @@ + + + Added SuspendStatus service which can be used by indexers to find out if + indexing is suspended. + + + + + +

+ The indexing is suspended by the infrastructure when high priority request like index query or execution + of UserTask, ParserResultTask is in progress. The SuspendStatus + allows indexers to find out that indexing is suspended or to park while it's suspended. +

+
+ + + +
Added IndexingAwareParserResultTask which is a specialization of ParserResultTask diff --git a/parsing.api/nbproject/project.properties b/parsing.api/nbproject/project.properties --- a/parsing.api/nbproject/project.properties +++ b/parsing.api/nbproject/project.properties @@ -3,4 +3,4 @@ javac.source=1.6 javadoc.apichanges=${basedir}/apichanges.xml javadoc.arch=${basedir}/arch.xml -spec.version.base=1.51.0 +spec.version.base=1.52.0 diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/Crawler.java b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/Crawler.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/Crawler.java +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/Crawler.java @@ -42,6 +42,7 @@ package org.netbeans.modules.parsing.impl.indexing; +import org.netbeans.modules.parsing.spi.indexing.SuspendStatus; import java.io.IOException; import java.net.URL; import java.util.ArrayList; diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/FileObjectCrawler.java @@ -42,6 +42,7 @@ package org.netbeans.modules.parsing.impl.indexing; +import org.netbeans.modules.parsing.spi.indexing.SuspendStatus; import java.io.File; import java.io.IOException; import java.util.Collection; diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/RepositoryUpdater.java b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/RepositoryUpdater.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/RepositoryUpdater.java +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/RepositoryUpdater.java @@ -110,15 +110,7 @@ import org.netbeans.modules.parsing.lucene.support.IndexManager; import org.netbeans.modules.parsing.spi.ParseException; import org.netbeans.modules.parsing.spi.Parser; -import org.netbeans.modules.parsing.spi.indexing.BinaryIndexer; -import org.netbeans.modules.parsing.spi.indexing.BinaryIndexerFactory; -import org.netbeans.modules.parsing.spi.indexing.Context; -import org.netbeans.modules.parsing.spi.indexing.CustomIndexer; -import org.netbeans.modules.parsing.spi.indexing.CustomIndexerFactory; -import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexer; -import org.netbeans.modules.parsing.spi.indexing.EmbeddingIndexerFactory; -import org.netbeans.modules.parsing.spi.indexing.Indexable; -import org.netbeans.modules.parsing.spi.indexing.SourceIndexerFactory; +import org.netbeans.modules.parsing.spi.indexing.*; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; @@ -176,7 +168,7 @@ scannedRoots2Peers, sourcesForBinaryRoots, false, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.PATH, null)); } } @@ -391,7 +383,7 @@ forceRefresh, sourcesForBinaryRoots.contains(rootUrl), steady, - suspendSupport, + suspendSupport.getSuspendStatus(), logCtx); } } else { @@ -402,7 +394,7 @@ checkEditor, forceRefresh, sourcesForBinaryRoots.contains(rootUrl), - suspendSupport, + suspendSupport.getSuspendStatus(), logCtx); } return flw; @@ -424,7 +416,7 @@ if (cifInfos == null) { throw new InvalidParameterException("No CustomIndexerFactory with name: '" + indexerName + "'"); //NOI18N } else { - Work w = new RefreshCifIndices(cifInfos, scannedRoots2Dependencies, sourcesForBinaryRoots, suspendSupport, logCtx); + Work w = new RefreshCifIndices(cifInfos, scannedRoots2Dependencies, sourcesForBinaryRoots, suspendSupport.getSuspendStatus(), logCtx); scheduleWork(w, false); } } @@ -453,7 +445,7 @@ logStatistics, filesOrFileObjects == null ? Collections.emptySet() : Arrays.asList(filesOrFileObjects), fsRefreshInterceptor, - suspendSupport, + suspendSupport.getSuspendStatus(), logCtx), wait); } @@ -541,7 +533,7 @@ scannedRoots2Peers, sourcesForBinaryRoots, !existingPathsChanged, - suspendSupport, + suspendSupport.getSuspendStatus(), logContext), false); } @@ -554,7 +546,7 @@ false, false, sourcesForBinaryRoots.contains(rootUrl), - suspendSupport, + suspendSupport.getSuspendStatus(), logContext), false); } @@ -662,7 +654,7 @@ scannedRoots2Peers, sourcesForBinaryRoots, false, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); } else { //Already seen files work is enough @@ -677,7 +669,7 @@ true, sourcForBinaryRoot, true, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); } else { //If no children nothing needs to be done - save some CPU time @@ -694,7 +686,7 @@ true, sourcForBinaryRoot, true, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); } if (wrk != null) { @@ -710,7 +702,7 @@ if (root != null && isVisible(fo, root.second)) { final Work wrk = new BinaryWork( root.first, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.CREATE, root.first, null, fe, wrk); processed = true; @@ -754,7 +746,7 @@ true, sourceForBinaryRoot, true, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.CREATE, root.first, FileUtil.getRelativePath(root.second, fo), fe, wrk); processed = true; @@ -767,7 +759,7 @@ if (root != null && isVisible(fo,root.second)) { final Work wrk = new BinaryWork( root.first, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.CREATE, root.first, null, fe, wrk); processed = true; @@ -816,7 +808,7 @@ final Work wrk = new DeleteWork( root.first, Collections.singleton(relativePath), - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.DELETE, root.first, relativePath, fe, wrk); processed = true; @@ -833,7 +825,7 @@ if (root != null && isVisible(fo, root.second)) { final Work wrk = new BinaryWork( root.first, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.DELETE, root.first, null, fe, wrk); processed = true; @@ -879,7 +871,7 @@ final Work work = new DeleteWork( root.first, Collections.singleton(oldFilePath), - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.DELETE, root.first, oldFilePath, fe, work); } else { @@ -889,7 +881,7 @@ final Work work = new DeleteWork( root.first, oldFilePaths, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.DELETE, root.first, path, fe, work); } @@ -908,7 +900,7 @@ true, sourceForBinaryRoot, true, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); eventQueue.record(FileEventLog.FileOp.CREATE, root.first, FileUtil.getRelativePath(rootFo, newFile), fe,flw); } @@ -930,7 +922,7 @@ null, fe, new BinaryWork(oldBinaryRoot, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null))); //NOI18N } catch (MalformedURLException mue) { LOGGER.log(Level.WARNING, null, mue); @@ -943,7 +935,7 @@ null, fe, new BinaryWork(root.first, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null))); processed = true; } @@ -977,7 +969,7 @@ changedIndexers, scannedRoots2Dependencies, sourcesForBinaryRoots, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.INDEXER,null)), false); } @@ -990,7 +982,7 @@ changedIndexers, scannedRoots2Dependencies, sourcesForBinaryRoots, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.INDEXER, null)), false); } @@ -1096,7 +1088,7 @@ true, sourcesForBinaryRoots.contains(root.first), true, - suspendSupport, + suspendSupport.getSuspendStatus(), LogContext.create(LogContext.EventType.FILE, null)); jobs.put(root.first, job); } else { @@ -1315,8 +1307,18 @@ for(IndexerCache.IndexerInfo info : cifInfos) { try { CustomIndexerFactory factory = info.getIndexerFactory(); - Context ctx = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.first), root.first, - factory.getIndexerName(), factory.getIndexVersion(), null, false, true, false, null); + Context ctx = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder(root.first), + root.first, + factory.getIndexerName(), + factory.getIndexVersion(), + null, + false, + true, + false, + SuspendSupport.NOP, + null, + null); factory.filesDirty(dirty, ctx); } catch (IOException ex) { LOGGER.log(Level.WARNING, null, ex); @@ -1327,8 +1329,18 @@ for(IndexerCache.IndexerInfo info : eifInfos) { try { EmbeddingIndexerFactory factory = info.getIndexerFactory(); - Context ctx = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.first), root.first, - factory.getIndexerName(), factory.getIndexVersion(), null, false, true, false, null); + Context ctx = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder(root.first), + root.first, + factory.getIndexerName(), + factory.getIndexVersion(), + null, + false, + true, + false, + SuspendSupport.NOP, + null, + null); factory.filesDirty(dirty, ctx); } catch (IOException ex) { LOGGER.log(Level.WARNING, null, ex); @@ -1391,7 +1403,7 @@ scannedRoots2Peers, sourcesForBinaryRoots, true, - suspendSupport, + suspendSupport.getSuspendStatus(), work == null ? LogContext.create(LogContext.EventType.PATH, null) : work.getLogContext()), false); @@ -2095,8 +2107,18 @@ final Pair key = Pair.of(factory.getIndexerName(),factory.getIndexVersion()); Pair value = ctxToFinish.get(key); if (value == null) { - final Context ctx = SPIAccessor.getInstance().createContext(cacheRoot, root, factory.getIndexerName(), factory.getIndexVersion(), null, - followUpJob, checkEditor, sourceForBinaryRoot, getShuttdownRequest()); + final Context ctx = SPIAccessor.getInstance().createContext( + cacheRoot, + root, + factory.getIndexerName(), + factory.getIndexVersion(), + null, + followUpJob, + checkEditor, + sourceForBinaryRoot, + getSuspendStatus(), + getShuttdownRequest(), + null); value = Pair.of(factory,ctx); ctxToFinish.put(key,value); } @@ -2124,8 +2146,18 @@ final Pair key = Pair.of(eif.getIndexerName(), eif.getIndexVersion()); Pair value = ctxToFinish.get(key); if (value == null) { - final Context context = SPIAccessor.getInstance().createContext(cacheRoot, root, eif.getIndexerName(), eif.getIndexVersion(), null, - followUpJob, checkEditor, sourceForBinaryRoot, null); + final Context context = SPIAccessor.getInstance().createContext( + cacheRoot, + root, + eif.getIndexerName(), + eif.getIndexVersion(), + null, + followUpJob, + checkEditor, + sourceForBinaryRoot, + getSuspendStatus(), + getShuttdownRequest(), + null); value = Pair.of(eif,context); ctxToFinish.put(key, value); } @@ -2284,7 +2316,18 @@ final Pair key = Pair.of(factory.getIndexerName(),factory.getIndexVersion()); Pair value = contexts.get(key); if (value == null) { - final Context ctx = SPIAccessor.getInstance().createContext(cacheRoot, root, factory.getIndexerName(), factory.getIndexVersion(), null, followUpJob, checkEditor, sourceForBinaryRoot, getShuttdownRequest()); + final Context ctx = SPIAccessor.getInstance().createContext( + cacheRoot, + root, + factory.getIndexerName(), + factory.getIndexVersion(), + null, + followUpJob, + checkEditor, + sourceForBinaryRoot, + getSuspendStatus(), + getShuttdownRequest(), + null); value = Pair.of(factory,ctx); contexts.put(key,value); } @@ -2383,7 +2426,18 @@ final Pair key = Pair.of(factory.getIndexerName(),factory.getIndexVersion()); Pair value = contexts.get(key); if (value == null) { - final Context ctx = SPIAccessor.getInstance().createContext(cacheRoot, root, factory.getIndexerName(), factory.getIndexVersion(), null, followUpJob, checkEditor, sourceForBinaryRoot, getShuttdownRequest()); + final Context ctx = SPIAccessor.getInstance().createContext( + cacheRoot, + root, + factory.getIndexerName(), + factory.getIndexVersion(), + null, + followUpJob, + checkEditor, + sourceForBinaryRoot, + getSuspendStatus(), + getShuttdownRequest(), + null); value = Pair.of(factory,ctx); contexts.put(key,value); } @@ -2482,8 +2536,17 @@ final FileObject cacheRoot = CacheFolder.getDataFolder(root); for(BinaryIndexerFactory bif : indexers.bifs) { final Context ctx = SPIAccessor.getInstance().createContext( - cacheRoot, root, bif.getIndexerName(), bif.getIndexVersion(), null, false, false, - false, getShuttdownRequest()); + cacheRoot, + root, + bif.getIndexerName(), + bif.getIndexVersion(), + null, + false, + false, + false, + getSuspendStatus(), + getShuttdownRequest(), + null); contexts.put(bif, ctx); } } @@ -2630,7 +2693,18 @@ final Pair key = Pair.of(indexerName,indexerVersion); Pair value = transactionContexts.get(key); if (value == null) { - final Context context = SPIAccessor.getInstance().createContext(cache, rootURL, indexerName, indexerVersion, null, followUpJob, checkEditor, sourceForBinaryRoot, null); + final Context context = SPIAccessor.getInstance().createContext( + cache, + rootURL, + indexerName, + indexerVersion, + null, + followUpJob, + checkEditor, + sourceForBinaryRoot, + getSuspendStatus(), + getShuttdownRequest(), + null); value = Pair.of(indexerFactory,context); transactionContexts.put(key,value); } diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SPIAccessor.java b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SPIAccessor.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SPIAccessor.java +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SPIAccessor.java @@ -89,26 +89,12 @@ boolean followUpJob, boolean checkForEditorModifications, boolean sourceForBinaryRoot, - CancelRequest cancelRequest, + @NonNull final SuspendStatus suspendedStatus, + @NullAllowed final CancelRequest cancelRequest, @NullAllowed final LogContext logContext) throws IOException; - - public final Context createContext ( - final FileObject indexFolder, final URL rootURL, - String indexerName, int indexerVersion, IndexFactoryImpl factory, - boolean followUpJob, boolean checkForEditorModifications, - boolean sourceForBinaryRoot, CancelRequest cancelRequest) throws IOException { - return createContext( - indexFolder, - rootURL, - indexerName, - indexerVersion, - factory, - followUpJob, - checkForEditorModifications, - sourceForBinaryRoot, - cancelRequest, - null); - } + + @NonNull + public abstract SuspendStatus createSuspendStatus(@NonNull SuspendSupport.SuspendStatusImpl impl); public abstract void context_attachIndexingSupport(Context context, IndexingSupport support); diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendSupport.java b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendSupport.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendSupport.java +++ b/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendSupport.java @@ -41,6 +41,7 @@ */ package org.netbeans.modules.parsing.impl.indexing; +import org.netbeans.modules.parsing.spi.indexing.SuspendStatus; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; @@ -53,7 +54,7 @@ * * @author Tomas Zezula */ -final class SuspendSupport implements SuspendStatus { +public final class SuspendSupport { private static final Logger LOG = Logger.getLogger(SuspendSupport.class.getName()); private static final boolean NO_SUSPEND = Boolean.getBoolean("SuspendSupport.disabled"); //NOI18N @@ -61,15 +62,33 @@ private final RequestProcessor worker; private final Object lock = new Object(); private final ThreadLocal ignoreSuspend = new ThreadLocal(); + private final SuspendStatus suspendStatus = SPIAccessor.getInstance().createSuspendStatus(new DefaultImpl()); //@GuardedBy("lock") private int suspedDepth; + + public static final SuspendStatus NOP = SPIAccessor.getInstance().createSuspendStatus(new NopImpl()); + + @NonNull + public SuspendStatus getSuspendStatus() { + return suspendStatus; + } + + public static interface SuspendStatusImpl { + public boolean isSuspended(); + public void parkWhileSuspended() throws InterruptedException; + } + + + +//-- Package private -- + SuspendSupport(@NonNull final RequestProcessor rp) { Parameters.notNull("rp", rp); //NOI18N this.worker = rp; } - public void suspend() { + void suspend() { if (NO_SUSPEND) { return; } @@ -87,7 +106,7 @@ } } - public void resume() { + void resume() { if (NO_SUSPEND) { return; } @@ -104,7 +123,7 @@ } } - public void runWithNoSuspend(final Runnable work) { + void runWithNoSuspend(final Runnable work) { ignoreSuspend.set(Boolean.TRUE); try { work.run(); @@ -112,36 +131,8 @@ ignoreSuspend.remove(); } } - - @Override - public boolean isSuspended() { - if (ignoreSuspend.get() == Boolean.TRUE) { - return false; - } - synchronized(lock) { - return suspedDepth > 0; - } - } - - @Override - public void parkWhileSuspended() throws InterruptedException { - if (ignoreSuspend.get() == Boolean.TRUE) { - return; - } - synchronized(lock) { - boolean parked = false; - while (suspedDepth > 0) { - LOG.fine("PARK"); //NOI18N - lock.wait(); - parked = true; - } - if (LOG.isLoggable(Level.FINE) && parked) { - LOG.fine("UNPARK"); //NOI18N - } - } - } - static final SuspendStatus NOP = new SuspendStatus () { + private static final class NopImpl implements SuspendStatusImpl { @Override public boolean isSuspended() { return false; @@ -149,6 +140,36 @@ @Override public void parkWhileSuspended() throws InterruptedException { } - }; + } + + private final class DefaultImpl implements SuspendStatusImpl { + @Override + public boolean isSuspended() { + if (ignoreSuspend.get() == Boolean.TRUE) { + return false; + } + synchronized(lock) { + return suspedDepth > 0; + } + } + + @Override + public void parkWhileSuspended() throws InterruptedException { + if (ignoreSuspend.get() == Boolean.TRUE) { + return; + } + synchronized(lock) { + boolean parked = false; + while (suspedDepth > 0) { + LOG.fine("PARK"); //NOI18N + lock.wait(); + parked = true; + } + if (LOG.isLoggable(Level.FINE) && parked) { + LOG.fine("UNPARK"); //NOI18N + } + } + } + } } diff --git a/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Context.java b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Context.java --- a/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Context.java +++ b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Context.java @@ -79,6 +79,7 @@ private final boolean checkForEditorModifications; private final boolean sourceForBinaryRoot; private final CancelRequest cancelRequest; + private final SuspendStatus suspendedStatus; private final LogContext logContext; private final Map props; private FileObject indexFolder; @@ -94,7 +95,8 @@ final IndexFactoryImpl factory, boolean followUpJob, final boolean checkForEditorModifications, final boolean sourceForBinaryRoot, - final CancelRequest cancelRequest, + @NonNull final SuspendStatus suspendedStatus, + @NullAllowed final CancelRequest cancelRequest, @NullAllowed final LogContext logContext ) throws IOException { assert indexBaseFolder != null; @@ -109,6 +111,7 @@ this.checkForEditorModifications = checkForEditorModifications; this.sourceForBinaryRoot = sourceForBinaryRoot; this.cancelRequest = cancelRequest; + this.suspendedStatus = suspendedStatus; this.logContext = logContext; this.props = new HashMap(); } @@ -256,6 +259,17 @@ public boolean isCancelled() { return cancelRequest == null ? false : cancelRequest.isRaised(); } + + /** + * Returns {@link SuspendStatus} providing information + * about indexing suspension. + * @return the {@link SuspendStatus} + * @since 1.52 + */ + @NonNull + public SuspendStatus getSuspendStatus() { + return suspendedStatus; + } // ----------------------------------------------------------------------- // Package private implementation diff --git a/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Indexable.java b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Indexable.java --- a/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Indexable.java +++ b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/Indexable.java @@ -54,6 +54,7 @@ import org.netbeans.modules.parsing.impl.indexing.LogContext; import org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater; import org.netbeans.modules.parsing.impl.indexing.SPIAccessor; +import org.netbeans.modules.parsing.impl.indexing.SuspendSupport.SuspendStatusImpl; import org.netbeans.modules.parsing.spi.Parser.Result; import org.netbeans.modules.parsing.spi.indexing.support.IndexingSupport; import org.openide.filesystems.FileObject; @@ -169,7 +170,8 @@ boolean followUpJob, boolean checkForEditorModifications, boolean sourceForBinaryRoot, - CancelRequest cancelRequest, + @NonNull SuspendStatus suspendedStatus, + @NullAllowed CancelRequest cancelRequest, @NullAllowed final LogContext logContext) throws IOException { return new Context( indexFolder, @@ -180,10 +182,17 @@ followUpJob, checkForEditorModifications, sourceForBinaryRoot, + suspendedStatus, cancelRequest, logContext); } + @NonNull + @Override + public SuspendStatus createSuspendStatus(@NonNull final SuspendStatusImpl impl) { + return new SuspendStatus(impl); + } + @Override public String getIndexerName(Context ctx) { assert ctx != null; diff --git a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendStatus.java b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/SuspendStatus.java rename from parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendStatus.java rename to parsing.api/src/org/netbeans/modules/parsing/spi/indexing/SuspendStatus.java --- a/parsing.api/src/org/netbeans/modules/parsing/impl/indexing/SuspendStatus.java +++ b/parsing.api/src/org/netbeans/modules/parsing/spi/indexing/SuspendStatus.java @@ -39,13 +39,52 @@ * * Portions Copyrighted 2011 Sun Microsystems, Inc. */ -package org.netbeans.modules.parsing.impl.indexing; +package org.netbeans.modules.parsing.spi.indexing; + +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.parsing.api.UserTask; +import org.netbeans.modules.parsing.impl.indexing.SuspendSupport; +import org.netbeans.modules.parsing.spi.ParserResultTask; +import org.openide.util.Parameters; /** - * + * A service for indexers to check if an indexing is suspended or + * to park while indexing is suspended. + * The indexing is suspended by the infrastructure when high priority request + * like index query or execution of {@link UserTask}, {@link ParserResultTask} + * is in progress. + * The instance of the {@link SuspendStatus} can be obtained from + * {@link Context#getSuspendStatus()}. The infrastructure suspends indexing + * automatically. The {@link EmbeddingIndexer}s are suspended with a file granularity. + * The {@link CustomIndexer}s are suspended with a source root granularity. + * This service can be used for more fine granularity suspending especially for + * {@link CustomIndexer}s. * @author Tomas Zezula + * @since 1.52 */ -interface SuspendStatus { - boolean isSuspended(); - void parkWhileSuspended() throws InterruptedException; +public final class SuspendStatus { + + private final SuspendSupport.SuspendStatusImpl impl; + + SuspendStatus(@NonNull final SuspendSupport.SuspendStatusImpl impl) { + Parameters.notNull("impl", impl); //NOI18N + this.impl = impl; + } + + /** + * Checks if an indexing is suspended. + * @return true if an indexing is suspended. + */ + public boolean isSuspended() { + return impl.isSuspended(); + } + + /** + * Parks a current (caller) thread while an indexing is suspended. + * Threading: The caller should not hold any locks when calling this method. + * @throws InterruptedException if the caller is interrupted. + */ + public void parkWhileSuspended() throws InterruptedException { + impl.parkWhileSuspended(); + } } diff --git a/parsing.api/test/unit/src/org/netbeans/modules/parsing/spi/indexing/support/IndexingSupportTest.java b/parsing.api/test/unit/src/org/netbeans/modules/parsing/spi/indexing/support/IndexingSupportTest.java --- a/parsing.api/test/unit/src/org/netbeans/modules/parsing/spi/indexing/support/IndexingSupportTest.java +++ b/parsing.api/test/unit/src/org/netbeans/modules/parsing/spi/indexing/support/IndexingSupportTest.java @@ -59,11 +59,7 @@ import org.netbeans.modules.parsing.impl.indexing.lucene.LuceneIndexFactory; import org.netbeans.modules.parsing.lucene.support.DocumentIndex; import org.netbeans.modules.parsing.lucene.support.Queries; -import org.netbeans.modules.parsing.spi.indexing.Context; -import org.netbeans.modules.parsing.spi.indexing.CustomIndexer; -import org.netbeans.modules.parsing.spi.indexing.CustomIndexerFactory; -import org.netbeans.modules.parsing.spi.indexing.Indexable; -import org.netbeans.modules.parsing.spi.indexing.PathRecognizer; +import org.netbeans.modules.parsing.spi.indexing.*; import org.netbeans.spi.java.classpath.ClassPathProvider; import org.netbeans.spi.java.classpath.support.ClassPathSupport; import org.openide.filesystems.FileObject; @@ -107,9 +103,32 @@ } public void testIndexingSupportInstances () throws Exception { - final Context ctx1 = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.getURL()), root.getURL(), "fooIndexer", 1, null, false, false, false, null); + final Context ctx1 = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder( + root.toURL()), + root.toURL(), + "fooIndexer", + 1, + null, + false, + false, + false, + SuspendSupport.NOP, + null, + null); assertNotNull(ctx1); - final Context ctx2 = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.getURL()), root.getURL(), "embIndexer", 1, null, false, false, false, null); + final Context ctx2 = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder(root.toURL()), + root.toURL(), + "embIndexer", + 1, + null, + false, + false, + false, + SuspendSupport.NOP, + null, + null); assertNotNull(ctx2); final IndexingSupport is1 = IndexingSupport.getInstance(ctx1); @@ -123,7 +142,18 @@ public void testIndexingQuerySupport () throws Exception { // index - final Context ctx = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.getURL()), root.getURL(), "fooIndexer", 1, null, false, false, false, null); + final Context ctx = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder(root.toURL()), + root.toURL(), + "fooIndexer", + 1, + null, + false, + false, + false, + SuspendSupport.NOP, + null, + null); assertNotNull(ctx); final Indexable i1 = SPIAccessor.getInstance().create(new FileObjectIndexable(root, f1)); final IndexingSupport is = IndexingSupport.getInstance(ctx); @@ -195,7 +225,18 @@ public void testQuerySupportCaching() throws Exception { // index - final Context ctx = SPIAccessor.getInstance().createContext(CacheFolder.getDataFolder(root.getURL()), root.getURL(), "fooIndexer", 1, null, false, false, false, null); + final Context ctx = SPIAccessor.getInstance().createContext( + CacheFolder.getDataFolder(root.toURL()), + root.toURL(), + "fooIndexer", + 1, + null, + false, + false, + false, + SuspendSupport.NOP, + null, + null); assertNotNull(ctx); final Indexable i1 = SPIAccessor.getInstance().create(new FileObjectIndexable(root, f1)); final IndexingSupport is = IndexingSupport.getInstance(ctx);