mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
introduce FileBasedIndex.processFilesContainingAnyKey
GitOrigin-RevId: 9fcacda8b2e13f8976bbb5a60d4483e34b24e899
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a96d2e233d
commit
1ad9a131f7
@@ -214,12 +214,10 @@ public final class FilenameIndex {
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@Nullable IdFilter filter) {
|
||||
Set<VirtualFile> files = CollectionFactory.createSmallMemoryFootprintSet();
|
||||
for (String name : names) {
|
||||
FileBasedIndex.getInstance().processValues(NAME, name, null, (file, value) -> {
|
||||
files.add(file);
|
||||
return true;
|
||||
}, scope, filter);
|
||||
}
|
||||
FileBasedIndex.getInstance().processFilesContainingAnyKey(NAME, names, scope, filter, null, file -> {
|
||||
files.add(file);
|
||||
return true;
|
||||
});
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,13 @@ public abstract class FileBasedIndex {
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor);
|
||||
|
||||
public abstract <K, V> boolean processFilesContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable IdFilter idFilter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor);
|
||||
|
||||
/**
|
||||
* It is guaranteed to return data which is up-to-date within the given project.
|
||||
* Keys obtained from the files which do not belong to the project specified may not be up-to-date or even exist.
|
||||
|
||||
@@ -375,6 +375,18 @@ public abstract class FileBasedIndexEx extends FileBasedIndex {
|
||||
return set != null && processVirtualFiles(set, filter, processor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> boolean processFilesContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable IdFilter idFilter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor) {
|
||||
IdFilter idFilterAdjusted = idFilter != null ? idFilter : extractIdFilter(filter, filter.getProject());
|
||||
IntSet set = collectFileIdsContainingAnyKey(indexId, dataKeys, filter, valueChecker, idFilterAdjusted);
|
||||
return set != null && processVirtualFiles(set, filter, processor);
|
||||
}
|
||||
|
||||
private boolean processFilesContainingAllKeysInPhysicalFiles(@NotNull Collection<? extends AllKeysQuery<?, ?>> queries,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
Processor<? super VirtualFile> processor,
|
||||
@@ -501,11 +513,11 @@ public abstract class FileBasedIndexEx extends FileBasedIndex {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <K, V> IntSet collectFileIdsContainingAllKeys(@NotNull final ID<K, V> indexId,
|
||||
@NotNull final Collection<? extends K> dataKeys,
|
||||
@NotNull final GlobalSearchScope filter,
|
||||
@Nullable final Condition<? super V> valueChecker,
|
||||
@Nullable final IdFilter projectFilesFilter,
|
||||
private <K, V> IntSet collectFileIdsContainingAllKeys(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@Nullable IdFilter projectFilesFilter,
|
||||
@Nullable IntSet restrictedIds) {
|
||||
IntPredicate accessibleFileFilter = getAccessibleFileIdFilter(filter.getProject());
|
||||
IntPredicate idChecker = id -> (projectFilesFilter == null || projectFilesFilter.containsFileId(id)) &&
|
||||
@@ -524,6 +536,28 @@ public abstract class FileBasedIndexEx extends FileBasedIndex {
|
||||
return processExceptions(indexId, null, filter, convertor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <K, V> IntSet collectFileIdsContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@Nullable IdFilter projectFilesFilter) {
|
||||
IntPredicate accessibleFileFilter = getAccessibleFileIdFilter(filter.getProject());
|
||||
IntPredicate idChecker = id -> (projectFilesFilter == null || projectFilesFilter.containsFileId(id)) &&
|
||||
accessibleFileFilter.test(id);
|
||||
ThrowableConvertor<UpdatableIndex<K, V, FileContent>, IntSet, StorageException> convertor = index -> {
|
||||
IndexDebugProperties.DEBUG_INDEX_ID.set(indexId);
|
||||
try {
|
||||
return InvertedIndexUtil.collectInputIdsContainingAnyKey(index, dataKeys, valueChecker, idChecker);
|
||||
}
|
||||
finally {
|
||||
IndexDebugProperties.DEBUG_INDEX_ID.remove();
|
||||
}
|
||||
};
|
||||
|
||||
return processExceptions(indexId, null, filter, convertor);
|
||||
}
|
||||
|
||||
private boolean processVirtualFiles(@NotNull IntCollection ids,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@NotNull Processor<? super VirtualFile> processor) {
|
||||
|
||||
@@ -37,7 +37,10 @@ import com.intellij.openapi.vfs.newvfs.ManagingFS;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
|
||||
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiBinaryFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiDocumentTransactionListener;
|
||||
import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
@@ -1146,6 +1149,19 @@ public final class FileBasedIndexImpl extends FileBasedIndexEx {
|
||||
return super.processFilesContainingAllKeys(indexId, dataKeys, filter, valueChecker, processor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> boolean processFilesContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable IdFilter idFilter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor) {
|
||||
IdFilter idFilterAdjusted = idFilter != null ? idFilter : extractIdFilter(filter, filter.getProject());
|
||||
Boolean scanResult = FileBasedIndexScanUtil.processFilesContainingAnyKey(indexId, dataKeys, filter, idFilterAdjusted, valueChecker, processor);
|
||||
if (scanResult != null) return scanResult;
|
||||
return super.processFilesContainingAnyKey(indexId, dataKeys, filter, idFilterAdjusted, valueChecker, processor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processFilesContainingAllKeys(@NotNull Collection<? extends AllKeysQuery<?, ?>> queries,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.BooleanSupplier;
|
||||
@@ -114,21 +115,20 @@ public final class FileBasedIndexScanUtil {
|
||||
if (indexId == FilenameIndex.NAME && Registry.is("indexing.filename.over.vfs")) {
|
||||
ensureIdFilterUpToDate();
|
||||
IntOpenHashSet ids = new IntOpenHashSet();
|
||||
FSRecords.processFilesWithName((String)dataKey, id -> {
|
||||
FSRecords.processFilesWithNames(Set.of((String)dataKey), id -> {
|
||||
if (idFilter != null && !idFilter.containsFileId(id)) return true;
|
||||
ids.add(id);
|
||||
return true;
|
||||
});
|
||||
InThisThreadProcessor threadProcessor = new InThisThreadProcessor();
|
||||
PersistentFS fs = PersistentFS.getInstance();
|
||||
IntIterator iterator = ids.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
VirtualFile file = fs.findFileById(iterator.nextInt());
|
||||
if (file == null || !scope.contains(file)) continue;
|
||||
if (!threadProcessor.process(() -> processor.process(file, null))) return false;
|
||||
if (!processor.process(file, null)) return false;
|
||||
if (ensureValueProcessedOnce) break;
|
||||
}
|
||||
return threadProcessor.processQueue();
|
||||
return true;
|
||||
}
|
||||
else if (indexId == FileTypeIndex.NAME && Registry.is("indexing.filetype.over.vfs")) {
|
||||
ensureIdFilterUpToDate();
|
||||
@@ -245,4 +245,33 @@ public final class FileBasedIndexScanUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <K, V> Boolean processFilesContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> keys,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@Nullable IdFilter idFilter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor) {
|
||||
if (indexId == FilenameIndex.NAME && Registry.is("indexing.filename.over.vfs")) {
|
||||
ensureIdFilterUpToDate();
|
||||
IntOpenHashSet ids = new IntOpenHashSet();
|
||||
//noinspection unchecked
|
||||
FSRecords.processFilesWithNames((Set<String>)keys, id -> {
|
||||
if (idFilter != null && !idFilter.containsFileId(id)) return true;
|
||||
ids.add(id);
|
||||
return true;
|
||||
});
|
||||
PersistentFS fs = PersistentFS.getInstance();
|
||||
IntIterator iterator = ids.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
VirtualFile file = fs.findFileById(iterator.nextInt());
|
||||
if (file == null || !scope.contains(file)) continue;
|
||||
//noinspection unchecked
|
||||
if (valueChecker != null && !valueChecker.value((V)file.getName())) continue;
|
||||
if (!processor.process(file)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,16 @@ public final class EmptyFileBasedIndex extends FileBasedIndexEx {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> boolean processFilesContainingAnyKey(@NotNull ID<K, V> indexId,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable IdFilter idFilter,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@NotNull Processor<? super VirtualFile> processor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <K> Collection<K> getAllKeys(@NotNull ID<K, ?> indexId, @NotNull Project project) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -65,4 +65,31 @@ public final class InvertedIndexUtil {
|
||||
|
||||
return mainIntersection == null ? IntSets.EMPTY_SET : mainIntersection;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <K, V, I> IntSet collectInputIdsContainingAnyKey(@NotNull InvertedIndex<? super K, V, I> index,
|
||||
@NotNull Collection<? extends K> dataKeys,
|
||||
@Nullable Condition<? super V> valueChecker,
|
||||
@Nullable IntPredicate idChecker) throws StorageException {
|
||||
IntSet result = null;
|
||||
for (K dataKey : dataKeys) {
|
||||
IOCancellationCallbackHolder.checkCancelled();
|
||||
ValueContainer<V> container = index.getData(dataKey);
|
||||
for (ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
|
||||
V value = valueIt.next();
|
||||
if (valueChecker != null && !valueChecker.value(value)) {
|
||||
continue;
|
||||
}
|
||||
IOCancellationCallbackHolder.checkCancelled();
|
||||
ValueContainer.IntIterator iterator = valueIt.getInputIdsIterator();
|
||||
while (iterator.hasNext()) {
|
||||
int id = iterator.next();
|
||||
if (idChecker != null && !idChecker.test(id)) continue;
|
||||
if (result == null) result = new IntOpenHashSet();
|
||||
result.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result == null ? IntSets.EMPTY_SET : result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.util.io.IOUtil;
|
||||
import com.intellij.util.io.PersistentHashMapValueStorage;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
@@ -37,6 +38,7 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntPredicate;
|
||||
@@ -555,12 +557,16 @@ public final class FSRecords {
|
||||
return readAndHandleErrors(() -> ourConnection.getNames().processAllDataObjects(processor));
|
||||
}
|
||||
|
||||
public static boolean processFilesWithName(@NotNull String name, @NotNull IntPredicate processor) {
|
||||
int nameId = getNameId(name);
|
||||
public static boolean processFilesWithNames(@NotNull Set<String> names, @NotNull IntPredicate processor) {
|
||||
if (names.isEmpty()) return true;
|
||||
IntOpenHashSet nameIds = new IntOpenHashSet();
|
||||
for (String name : names) {
|
||||
nameIds.add(getNameId(name));
|
||||
}
|
||||
return readAndHandleErrors(() -> {
|
||||
PersistentFSRecordsStorage records = ourConnection.getRecords();
|
||||
return records.processAll(r -> {
|
||||
if (r.name == nameId &&
|
||||
if (nameIds.contains(r.name) &&
|
||||
!(BitUtil.isSet(r.flags, PersistentFSRecordAccessor.FREE_RECORD_FLAG) ||
|
||||
ourRecordAccessor.getNewFreeRecords().contains(r.id))) {
|
||||
if (!processor.test(r.id)) return false;
|
||||
|
||||
Reference in New Issue
Block a user