public boolean processFilesWithText(@NotNull final GlobalSearchScope scope, final short searchContext, final boolean caseSensitively, @NotNull String text, @NotNull final Processor<VirtualFile> processor) { List<IdIndexEntry> entries = getWordEntries(text, caseSensitively); if (entries.isEmpty()) return true; Condition<Integer> contextMatches = new Condition<Integer>() { @Override public boolean value(Integer integer) { return (integer.intValue() & searchContext) != 0; } }; return processFilesContainingAllKeys(myManager.getProject(), scope, contextMatches, entries, processor); }
private static boolean processFilesContainingAllKeys(@NotNull Project project, @NotNull final GlobalSearchScope scope, @Nullable final Condition<Integer> checker, @NotNull final Collection<IdIndexEntry> keys, @NotNull final Processor<VirtualFile> processor) { final FileIndexFacade index = FileIndexFacade.getInstance(project); return DumbService.getInstance(project).runReadActionInSmartMode(new Computable<Boolean>() { @Override public Boolean compute() { return FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, keys, scope, checker, new Processor<VirtualFile>() { @Override public boolean process(VirtualFile file) { return !index.shouldBeFound(scope, file) || processor.process(file); } }); } }); }
@NotNull private static List<IdIndexEntry> getWordEntries(@NotNull String name, final boolean caseSensitively) { List<String> words = StringUtil.getWordsInStringLongestFirst(name); if (words.isEmpty()) { String trimmed = name.trim(); if (StringUtil.isNotEmpty(trimmed)) { words = Collections.singletonList(trimmed); } } if (words.isEmpty()) return Collections.emptyList(); return ContainerUtil.map2List(words, new Function<String, IdIndexEntry>() { @Override public IdIndexEntry fun(String word) { return new IdIndexEntry(word, caseSensitively); } }); }
public boolean processFilesWithText(@NotNull final GlobalSearchScope scope, final short searchContext, final boolean caseSensitively, @NotNull String text, @NotNull final Processor<VirtualFile> processor) { List<IdIndexEntry> entries = getWordEntries(text, caseSensitively); if (entries.isEmpty()) return true; final CommonProcessors.CollectProcessor<VirtualFile> collectProcessor = new CommonProcessors.CollectProcessor<VirtualFile>(); processFilesContainingAllKeys(scope, new Condition<Integer>() { @Override public boolean value(Integer integer) { return (integer.intValue() & searchContext) != 0; } }, collectProcessor, entries); final FileIndexFacade index = FileIndexFacade.getInstance(myManager.getProject()); return ContainerUtil.process(collectProcessor.getResults(), new ReadActionProcessor<VirtualFile>() { @Override public boolean processInReadAction(VirtualFile virtualFile) { return !index.shouldBeFound(scope, virtualFile) || processor.process(virtualFile); } }); }
@Override public boolean processRequests(@NotNull SearchRequestCollector collector, @NotNull Processor<PsiReference> processor) { final Map<SearchRequestCollector, Processor<PsiReference>> collectors = ContainerUtil.newHashMap(); collectors.put(collector, processor); ProgressIndicator progress = getOrCreateIndicator(); appendCollectorsFromQueryRequests(collectors); boolean result; do { MultiMap<Set<IdIndexEntry>, RequestWithProcessor> globals = new MultiMap<Set<IdIndexEntry>, RequestWithProcessor>(); final List<Computable<Boolean>> customs = ContainerUtil.newArrayList(); final Set<RequestWithProcessor> locals = ContainerUtil.newLinkedHashSet(); Map<RequestWithProcessor, Processor<PsiElement>> localProcessors = new THashMap<RequestWithProcessor, Processor<PsiElement>>(); distributePrimitives(collectors, locals, globals, customs, localProcessors, progress); result = processGlobalRequestsOptimized(globals, progress, localProcessors); if (result) { for (RequestWithProcessor local : locals) { result = processSingleRequest(local.request, local.refProcessor); if (!result) break; } if (result) { for (Computable<Boolean> custom : customs) { result = custom.compute(); if (!result) break; } } if (!result) break; } } while(appendCollectorsFromQueryRequests(collectors)); return result; }
@NotNull @Override public SearchCostResult isCheapEnoughToSearch(@NotNull String name, @NotNull final GlobalSearchScope scope, @Nullable final PsiFile fileToIgnoreOccurrencesIn, @Nullable final ProgressIndicator progress) { final AtomicInteger count = new AtomicInteger(); final ProgressIndicator indicator = progress == null ? new EmptyProgressIndicator() : progress; final Processor<VirtualFile> processor = new Processor<VirtualFile>() { private final VirtualFile virtualFileToIgnoreOccurrencesIn = fileToIgnoreOccurrencesIn == null ? null : fileToIgnoreOccurrencesIn.getVirtualFile(); @Override public boolean process(VirtualFile file) { indicator.checkCanceled(); if (Comparing.equal(file, virtualFileToIgnoreOccurrencesIn)) return true; final int value = count.incrementAndGet(); return value < 10; } }; List<IdIndexEntry> keys = getWordEntries(name, true); boolean cheap = keys.isEmpty() || processFilesContainingAllKeys(myManager.getProject(), scope, null, keys, processor); if (!cheap) { return SearchCostResult.TOO_MANY_OCCURRENCES; } return count.get() == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES; }
private boolean collectVirtualFilesWithWord(@NotNull final Processor<VirtualFile> fileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) { if (myProject.isDefault()) { return true; } try { return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { @Override public Boolean compute() { return FileBasedIndex.getInstance().processValues(IdIndex.NAME, new IdIndexEntry(word, caseSensitively), null, new FileBasedIndex.ValueProcessor<Integer>() { final FileIndexFacade index = FileIndexFacade.getInstance(myProject); @Override public boolean process(final VirtualFile file, final Integer value) { ProgressIndicatorProvider.checkCanceled(); final int mask = value.intValue(); if ((mask & occurrenceMask) != 0 && index.shouldBeFound(scope, file)) { if (!fileProcessor.process(file)) return false; } return true; } }, scope); } }); } catch (IndexNotReadyException e) { throw new ProcessCanceledException(); } }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().isInLocalFileSystem(); // same as TodoIndex.getFilter().isAcceptable final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
public Map<IdIndexEntry, Integer> getResult() { final Map<IdIndexEntry, Integer> result = new THashMap<IdIndexEntry, Integer>(myResult.size()); myResult.forEachEntry(new TIntIntProcedure() { @Override public boolean execute(final int key, final int value) { result.put(new IdIndexEntry(key), value); return true; } }); return result; }
@NotNull private static MultiMap<VirtualFile, RequestWithProcessor> findFilesWithIndexEntry(@NotNull final IdIndexEntry entry, @NotNull final FileIndexFacade index, @NotNull final Collection<RequestWithProcessor> data, @NotNull final GlobalSearchScope commonScope, final ProgressIndicator progress) { final MultiMap<VirtualFile, RequestWithProcessor> local = createMultiMap(); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { if (progress != null) progress.checkCanceled(); FileBasedIndex.getInstance().processValues(IdIndex.NAME, entry, null, new FileBasedIndex.ValueProcessor<Integer>() { @Override public boolean process(VirtualFile file, Integer value) { if (progress != null) progress.checkCanceled(); if (index.shouldBeFound(commonScope, file)) { int mask = value.intValue(); for (RequestWithProcessor single : data) { final PsiSearchRequest request = single.request; if ((mask & request.searchContext) != 0 && ((GlobalSearchScope)request.searchScope).contains(file)) { local.putValue(file, single); } } } return true; } }, commonScope); } }); return local; }
@NotNull @Override public SearchCostResult isCheapEnoughToSearch(@NotNull String name, @NotNull final GlobalSearchScope scope, @Nullable final PsiFile fileToIgnoreOccurencesIn, @Nullable final ProgressIndicator progress) { final AtomicInteger count = new AtomicInteger(); final FileIndexFacade index = FileIndexFacade.getInstance(myManager.getProject()); final Processor<VirtualFile> processor = new Processor<VirtualFile>() { private final VirtualFile fileToIgnoreOccurencesInVirtualFile = fileToIgnoreOccurencesIn != null ? fileToIgnoreOccurencesIn.getVirtualFile() : null; @Override public boolean process(VirtualFile file) { if (progress != null) progress.checkCanceled(); if (Comparing.equal(file, fileToIgnoreOccurencesInVirtualFile)) return true; if (!index.shouldBeFound(scope, file)) return true; final int value = count.incrementAndGet(); return value < 10; } }; List<IdIndexEntry> keys = getWordEntries(name, true); boolean cheap = keys.isEmpty() || processFilesContainingAllKeys(scope, null, processor, keys); if (!cheap) { return SearchCostResult.TOO_MANY_OCCURRENCES; } return count.get() == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES; }
private static boolean processFilesContainingAllKeys(@NotNull final GlobalSearchScope scope, @Nullable final Condition<Integer> checker, @NotNull final Processor<VirtualFile> processor, @NotNull final Collection<IdIndexEntry> keys) { return ApplicationManager.getApplication().runReadAction(new NullableComputable<Boolean>() { @Override public Boolean compute() { return FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, keys, scope, checker, processor); } }); }
@NotNull private static List<IdIndexEntry> getWordEntries(@NotNull String name, boolean caseSensitively) { List<String> words = StringUtil.getWordsInStringLongestFirst(name); final ArrayList<IdIndexEntry> keys = new ArrayList<IdIndexEntry>(); for (String word : words) { keys.add(new IdIndexEntry(word, caseSensitively)); } return keys; }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().getFileSystem().getProtocol().equals(StandardFileSystems.FILE_PROTOCOL); final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
private static ArrayList<IdIndexEntry> getWordEntries(String name, boolean caseSensitively) { List<String> words = StringUtil.getWordsInStringLongestFirst(name); final ArrayList<IdIndexEntry> keys = new ArrayList<IdIndexEntry>(); for (String word : words) { keys.add(new IdIndexEntry(word, caseSensitively)); } return keys; }
public boolean processFilesWithText(@Nonnull final GlobalSearchScope scope, final short searchContext, final boolean caseSensitively, @Nonnull String text, @Nonnull final Processor<VirtualFile> processor) { List<IdIndexEntry> entries = getWordEntries(text, caseSensitively); if (entries.isEmpty()) return true; Condition<Integer> contextMatches = integer -> (integer.intValue() & searchContext) != 0; return processFilesContainingAllKeys(myManager.getProject(), scope, contextMatches, entries, processor); }
@Override public boolean processRequests(@Nonnull SearchRequestCollector collector, @Nonnull Processor<PsiReference> processor) { final Map<SearchRequestCollector, Processor<PsiReference>> collectors = ContainerUtil.newHashMap(); collectors.put(collector, processor); ProgressIndicator progress = getOrCreateIndicator(); appendCollectorsFromQueryRequests(collectors); boolean result; do { MultiMap<Set<IdIndexEntry>, RequestWithProcessor> globals = new MultiMap<>(); final List<Computable<Boolean>> customs = ContainerUtil.newArrayList(); final Set<RequestWithProcessor> locals = ContainerUtil.newLinkedHashSet(); Map<RequestWithProcessor, Processor<PsiElement>> localProcessors = new THashMap<>(); distributePrimitives(collectors, locals, globals, customs, localProcessors, progress); result = processGlobalRequestsOptimized(globals, progress, localProcessors); if (result) { for (RequestWithProcessor local : locals) { result = processSingleRequest(local.request, local.refProcessor); if (!result) break; } if (result) { for (Computable<Boolean> custom : customs) { result = custom.compute(); if (!result) break; } } if (!result) break; } } while(appendCollectorsFromQueryRequests(collectors)); return result; }
private void collectFiles(@Nonnull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles, @Nonnull ProgressIndicator progress, @Nonnull final MultiMap<VirtualFile, RequestWithProcessor> intersectionResult, @Nonnull final MultiMap<VirtualFile, RequestWithProcessor> restResult) { for (Map.Entry<Set<IdIndexEntry>, Collection<RequestWithProcessor>> entry : singles.entrySet()) { final Set<IdIndexEntry> keys = entry.getKey(); if (keys.isEmpty()) { continue; } final Collection<RequestWithProcessor> processors = entry.getValue(); final GlobalSearchScope commonScope = uniteScopes(processors); final Set<VirtualFile> intersectionWithContainerNameFiles = intersectionWithContainerNameFiles(commonScope, processors, keys); List<VirtualFile> result = new ArrayList<>(); Processor<VirtualFile> processor = Processors.cancelableCollectProcessor(result); processFilesContainingAllKeys(myManager.getProject(), commonScope, null, keys, processor); for (final VirtualFile file : result) { progress.checkCanceled(); for (final IdIndexEntry indexEntry : keys) { myDumbService.runReadActionInSmartMode( () -> FileBasedIndex.getInstance().processValues(IdIndex.NAME, indexEntry, file, (file1, value) -> { int mask = value.intValue(); for (RequestWithProcessor single : processors) { final PsiSearchRequest request = single.request; if ((mask & request.searchContext) != 0 && request.searchScope.contains(file1)) { MultiMap<VirtualFile, RequestWithProcessor> result1 = intersectionWithContainerNameFiles == null || !intersectionWithContainerNameFiles.contains(file1) ? restResult : intersectionResult; result1.putValue(file1, single); } } return true; }, commonScope)); } } } }
/** * @return null means we did not find common container files */ @Nullable private Set<VirtualFile> intersectionWithContainerNameFiles(@Nonnull GlobalSearchScope commonScope, @Nonnull Collection<RequestWithProcessor> data, @Nonnull Set<IdIndexEntry> keys) { String commonName = null; short searchContext = 0; boolean caseSensitive = true; for (RequestWithProcessor r : data) { String containerName = r.request.containerName; if (containerName != null) { if (commonName == null) { commonName = containerName; searchContext = r.request.searchContext; caseSensitive = r.request.caseSensitive; } else if (commonName.equals(containerName)) { searchContext |= r.request.searchContext; caseSensitive &= r.request.caseSensitive; } else { return null; } } } if (commonName == null) return null; List<IdIndexEntry> entries = getWordEntries(commonName, caseSensitive); if (entries.isEmpty()) return null; entries.addAll(keys); // should find words from both text and container names final short finalSearchContext = searchContext; Condition<Integer> contextMatches = context -> (context.intValue() & finalSearchContext) != 0; Set<VirtualFile> containerFiles = new THashSet<>(); Processor<VirtualFile> processor = Processors.cancelableCollectProcessor(containerFiles); processFilesContainingAllKeys(myManager.getProject(), commonScope, contextMatches, entries, processor); return containerFiles; }
private static void distributePrimitives(@Nonnull Map<SearchRequestCollector, Processor<PsiReference>> collectors, @Nonnull Set<RequestWithProcessor> locals, @Nonnull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> globals, @Nonnull List<Computable<Boolean>> customs, @Nonnull Map<RequestWithProcessor, Processor<PsiElement>> localProcessors, @Nonnull ProgressIndicator progress) { for (final Map.Entry<SearchRequestCollector, Processor<PsiReference>> entry : collectors.entrySet()) { final Processor<PsiReference> processor = entry.getValue(); SearchRequestCollector collector = entry.getKey(); for (final PsiSearchRequest primitive : collector.takeSearchRequests()) { final SearchScope scope = primitive.searchScope; if (scope instanceof LocalSearchScope) { registerRequest(locals, primitive, processor); } else { Set<IdIndexEntry> key = new HashSet<>(getWordEntries(primitive.word, primitive.caseSensitive)); registerRequest(globals.getModifiable(key), primitive, processor); } } for (final Processor<Processor<PsiReference>> customAction : collector.takeCustomSearchActions()) { customs.add(() -> customAction.process(processor)); } } for (Map.Entry<Set<IdIndexEntry>, Collection<RequestWithProcessor>> entry : globals.entrySet()) { for (RequestWithProcessor singleRequest : entry.getValue()) { PsiSearchRequest primitive = singleRequest.request; StringSearcher searcher = new StringSearcher(primitive.word, primitive.caseSensitive, true, false); BulkOccurrenceProcessor adapted = adaptProcessor(primitive, singleRequest.refProcessor); Processor<PsiElement> localProcessor = localProcessor(adapted, progress, searcher); assert !localProcessors.containsKey(singleRequest) || localProcessors.get(singleRequest) == localProcessor; localProcessors.put(singleRequest, localProcessor); } } }
@Nonnull @Override public SearchCostResult isCheapEnoughToSearch(@Nonnull String name, @Nonnull final GlobalSearchScope scope, @javax.annotation.Nullable final PsiFile fileToIgnoreOccurrencesIn, @javax.annotation.Nullable final ProgressIndicator progress) { final AtomicInteger count = new AtomicInteger(); final ProgressIndicator indicator = progress == null ? new EmptyProgressIndicator() : progress; final Processor<VirtualFile> processor = new Processor<VirtualFile>() { private final VirtualFile virtualFileToIgnoreOccurrencesIn = fileToIgnoreOccurrencesIn == null ? null : fileToIgnoreOccurrencesIn.getVirtualFile(); @Override public boolean process(VirtualFile file) { indicator.checkCanceled(); if (Comparing.equal(file, virtualFileToIgnoreOccurrencesIn)) return true; final int value = count.incrementAndGet(); return value < 10; } }; List<IdIndexEntry> keys = getWordEntries(name, true); boolean cheap = keys.isEmpty() || processFilesContainingAllKeys(myManager.getProject(), scope, null, keys, processor); if (!cheap) { return SearchCostResult.TOO_MANY_OCCURRENCES; } return count.get() == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES; }
private static boolean processFilesContainingAllKeys(@Nonnull Project project, @Nonnull final GlobalSearchScope scope, @javax.annotation.Nullable final Condition<Integer> checker, @Nonnull final Collection<IdIndexEntry> keys, @Nonnull final Processor<VirtualFile> processor) { final FileIndexFacade index = FileIndexFacade.getInstance(project); return DumbService.getInstance(project).runReadActionInSmartMode( () -> FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, keys, scope, checker, file -> !index.shouldBeFound(scope, file) || processor.process(file))); }
@Nonnull private static List<IdIndexEntry> getWordEntries(@Nonnull String name, final boolean caseSensitively) { List<String> words = StringUtil.getWordsInStringLongestFirst(name); if (words.isEmpty()) { String trimmed = name.trim(); if (StringUtil.isNotEmpty(trimmed)) { words = Collections.singletonList(trimmed); } } if (words.isEmpty()) return Collections.emptyList(); return ContainerUtil.map2List(words, word -> new IdIndexEntry(word, caseSensitively)); }
private boolean collectVirtualFilesWithWord(@Nonnull final Processor<VirtualFile> fileProcessor, @Nonnull final String word, final short occurrenceMask, @Nonnull final GlobalSearchScope scope, final boolean caseSensitively) { if (myProject.isDefault()) { return true; } try { return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { @Override public Boolean compute() { return FileBasedIndex.getInstance().processValues(IdIndex.NAME, new IdIndexEntry(word, caseSensitively), null, new FileBasedIndex.ValueProcessor<Integer>() { final FileIndexFacade index = FileIndexFacade.getInstance(myProject); @Override public boolean process(final VirtualFile file, final Integer value) { ProgressIndicatorProvider.checkCanceled(); final int mask = value.intValue(); if ((mask & occurrenceMask) != 0 && index.shouldBeFound(scope, file)) { if (!fileProcessor.process(file)) return false; } return true; } }, scope); } }); } catch (IndexNotReadyException e) { throw new ProcessCanceledException(); } }
public static ScanContent scanContent(FileContent content, IdAndToDoScannerBasedOnFilterLexer indexer) { ScanContent data = content.getUserData(scanContentKey); if (data != null) { content.putUserData(scanContentKey, null); return data; } final boolean needTodo = content.getFile().getFileSystem() instanceof LocalFileSystem; final boolean needIdIndex = IdTableBuilding.getFileTypeIndexer(content.getFileType()) instanceof LexerBasedIdIndexer; final IdDataConsumer consumer = needIdIndex? new IdDataConsumer():null; final OccurrenceConsumer todoOccurrenceConsumer = new OccurrenceConsumer(consumer, needTodo); final Lexer filterLexer = indexer.createLexer(todoOccurrenceConsumer); filterLexer.start(content.getContentAsText()); while (filterLexer.getTokenType() != null) filterLexer.advance(); Map<TodoIndexEntry,Integer> todoMap = null; if (needTodo) { for (IndexPattern indexPattern : IndexPatternUtil.getIndexPatterns()) { final int count = todoOccurrenceConsumer.getOccurrenceCount(indexPattern); if (count > 0) { if (todoMap == null) todoMap = new THashMap<TodoIndexEntry, Integer>(); todoMap.put(new TodoIndexEntry(indexPattern.getPatternString(), indexPattern.isCaseSensitive()), count); } } } data = new ScanContent( consumer != null? consumer.getResult():Collections.<IdIndexEntry, Integer>emptyMap(), todoMap != null ? todoMap: Collections.<TodoIndexEntry,Integer>emptyMap() ); if (needIdIndex && needTodo) content.putUserData(scanContentKey, data); return data; }
private boolean processGlobalRequestsOptimized(@NotNull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles, @NotNull ProgressIndicator progress, @NotNull final Map<RequestWithProcessor, Processor<PsiElement>> localProcessors) { if (singles.isEmpty()) { return true; } if (singles.size() == 1) { final Collection<? extends RequestWithProcessor> requests = singles.values(); if (requests.size() == 1) { final RequestWithProcessor theOnly = requests.iterator().next(); return processSingleRequest(theOnly.request, theOnly.refProcessor); } } progress.pushState(); progress.setText(PsiBundle.message("psi.scanning.files.progress")); boolean result; try { // intersectionCandidateFiles holds files containing words from all requests in `singles` and words in corresponding container names final MultiMap<VirtualFile, RequestWithProcessor> intersectionCandidateFiles = createMultiMap(); // restCandidateFiles holds files containing words from all requests in `singles` but EXCLUDING words in corresponding container names final MultiMap<VirtualFile, RequestWithProcessor> restCandidateFiles = createMultiMap(); collectFiles(singles, progress, intersectionCandidateFiles, restCandidateFiles); if (intersectionCandidateFiles.isEmpty() && restCandidateFiles.isEmpty()) { return true; } final Set<String> allWords = new TreeSet<String>(); for (RequestWithProcessor singleRequest : localProcessors.keySet()) { allWords.add(singleRequest.request.word); } progress.setText(PsiBundle.message("psi.search.for.word.progress", getPresentableWordsDescription(allWords))); if (intersectionCandidateFiles.isEmpty()) { result = processCandidates(localProcessors, restCandidateFiles, progress, restCandidateFiles.size(), 0); } else { int totalSize = restCandidateFiles.size() + intersectionCandidateFiles.size(); result = processCandidates(localProcessors, intersectionCandidateFiles, progress, totalSize, 0); if (result) { result = processCandidates(localProcessors, restCandidateFiles, progress, totalSize, intersectionCandidateFiles.size()); } } } finally { progress.popState(); } return result; }
@Nullable("null means we did not find common container files") private Set<VirtualFile> intersectionWithContainerNameFiles(@NotNull GlobalSearchScope commonScope, @NotNull Collection<RequestWithProcessor> data, @NotNull Set<IdIndexEntry> keys) { String commonName = null; short searchContext = 0; boolean caseSensitive = true; for (RequestWithProcessor r : data) { String name = r.request.containerName; if (name != null) { if (commonName == null) { commonName = r.request.containerName; searchContext = r.request.searchContext; caseSensitive = r.request.caseSensitive; } else if (commonName.equals(name)) { searchContext |= r.request.searchContext; caseSensitive &= r.request.caseSensitive; } else { return null; } } } if (commonName == null) return null; Set<VirtualFile> containerFiles = new THashSet<VirtualFile>(); List<IdIndexEntry> entries = getWordEntries(commonName, caseSensitive); if (entries.isEmpty()) return null; entries.addAll(keys); // should find words from both text and container names final short finalSearchContext = searchContext; Condition<Integer> contextMatches = new Condition<Integer>() { @Override public boolean value(Integer context) { return (context.intValue() & finalSearchContext) != 0; } }; processFilesContainingAllKeys(myManager.getProject(), commonScope, contextMatches, entries, new CommonProcessors.CollectProcessor<VirtualFile>(containerFiles)); return containerFiles; }
private static void distributePrimitives(@NotNull Map<SearchRequestCollector, Processor<PsiReference>> collectors, @NotNull Set<RequestWithProcessor> locals, @NotNull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles, @NotNull List<Computable<Boolean>> customs, @NotNull Map<RequestWithProcessor, Processor<PsiElement>> localProcessors, @NotNull ProgressIndicator progress) { for (final Map.Entry<SearchRequestCollector, Processor<PsiReference>> entry : collectors.entrySet()) { final Processor<PsiReference> processor = entry.getValue(); SearchRequestCollector collector = entry.getKey(); for (final PsiSearchRequest primitive : collector.takeSearchRequests()) { final SearchScope scope = primitive.searchScope; if (scope instanceof LocalSearchScope) { registerRequest(locals, primitive, processor); } else { Set<IdIndexEntry> key = new HashSet<IdIndexEntry>(getWordEntries(primitive.word, primitive.caseSensitive)); registerRequest(singles.getModifiable(key), primitive, processor); } } for (final Processor<Processor<PsiReference>> customAction : collector.takeCustomSearchActions()) { customs.add(new Computable<Boolean>() { @Override public Boolean compute() { return customAction.process(processor); } }); } } for (Map.Entry<Set<IdIndexEntry>, Collection<RequestWithProcessor>> entry : singles.entrySet()) { for (RequestWithProcessor singleRequest : entry.getValue()) { PsiSearchRequest primitive = singleRequest.request; StringSearcher searcher = new StringSearcher(primitive.word, primitive.caseSensitive, true, false); final TextOccurenceProcessor adapted = adaptProcessor(primitive, singleRequest.refProcessor); Processor<PsiElement> localProcessor = localProcessor(adapted, progress, true, searcher); assert !localProcessors.containsKey(singleRequest) || localProcessors.get(singleRequest) == localProcessor; localProcessors.put(singleRequest, localProcessor); } } }
public ScanContent(Map<IdIndexEntry, Integer> _idMap, Map<TodoIndexEntry, Integer> _todoMap) { idMap = _idMap; todoMap = _todoMap; }
private boolean processGlobalRequestsOptimized(@Nonnull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles, @Nonnull ProgressIndicator progress, @Nonnull final Map<RequestWithProcessor, Processor<PsiElement>> localProcessors) { if (singles.isEmpty()) { return true; } if (singles.size() == 1) { final Collection<? extends RequestWithProcessor> requests = singles.values(); if (requests.size() == 1) { final RequestWithProcessor theOnly = requests.iterator().next(); return processSingleRequest(theOnly.request, theOnly.refProcessor); } } progress.pushState(); progress.setText(PsiBundle.message("psi.scanning.files.progress")); boolean result; try { // intersectionCandidateFiles holds files containing words from all requests in `singles` and words in corresponding container names final MultiMap<VirtualFile, RequestWithProcessor> intersectionCandidateFiles = createMultiMap(); // restCandidateFiles holds files containing words from all requests in `singles` but EXCLUDING words in corresponding container names final MultiMap<VirtualFile, RequestWithProcessor> restCandidateFiles = createMultiMap(); collectFiles(singles, progress, intersectionCandidateFiles, restCandidateFiles); if (intersectionCandidateFiles.isEmpty() && restCandidateFiles.isEmpty()) { return true; } final Set<String> allWords = new TreeSet<>(); for (RequestWithProcessor singleRequest : localProcessors.keySet()) { allWords.add(singleRequest.request.word); } progress.setText(PsiBundle.message("psi.search.for.word.progress", getPresentableWordsDescription(allWords))); if (intersectionCandidateFiles.isEmpty()) { result = processCandidates(localProcessors, restCandidateFiles, progress, restCandidateFiles.size(), 0); } else { int totalSize = restCandidateFiles.size() + intersectionCandidateFiles.size(); result = processCandidates(localProcessors, intersectionCandidateFiles, progress, totalSize, 0); if (result) { result = processCandidates(localProcessors, restCandidateFiles, progress, totalSize, intersectionCandidateFiles.size()); } } } finally { progress.popState(); } return result; }