mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
process iteration over smaller set when intersecting file sets with occurences,
also more efficient merged data calculation by cloning data retrieved from disk
This commit is contained in:
+12
-8
@@ -108,6 +108,11 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
return getMergedData().isAssociated(value, inputId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntPredicate getValueAssociationPredicate(Value value) {
|
||||
return getMergedData().getValueAssociationPredicate(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntIterator getInputIdsIterator(final Value value) {
|
||||
return getMergedData().getInputIdsIterator(value);
|
||||
@@ -119,7 +124,7 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
|
||||
// need 'synchronized' to ensure atomic initialization of merged data
|
||||
// because several threads that acquired read lock may simultaneously execute the method
|
||||
private ValueContainer<Value> getMergedData() {
|
||||
private ValueContainerImpl<Value> getMergedData() {
|
||||
ValueContainerImpl<Value> merged = myMerged;
|
||||
if (merged != null) {
|
||||
return merged;
|
||||
@@ -129,16 +134,15 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
if (merged != null) {
|
||||
return merged;
|
||||
}
|
||||
final ValueContainerImpl<Value> newMerged = new ValueContainerImpl<Value>();
|
||||
|
||||
final ValueContainer<Value> fromDisk = myInitializer.compute();
|
||||
final ValueContainerImpl<Value> newMerged;
|
||||
|
||||
fromDisk.forEach(new ContainerAction<Value>() {
|
||||
@Override
|
||||
public void perform(final int id, final Value value) {
|
||||
newMerged.addValue(id, value);
|
||||
}
|
||||
});
|
||||
if (fromDisk instanceof ValueContainerImpl) {
|
||||
newMerged = ((ValueContainerImpl<Value>)fromDisk).clone();
|
||||
} else {
|
||||
newMerged = ((ChangeTrackingValueContainer<Value>)fromDisk).getMergedData().clone();
|
||||
}
|
||||
myInvalidated.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int inputId) {
|
||||
|
||||
@@ -63,8 +63,6 @@ import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ConcurrentHashSet;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.io.*;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import com.intellij.util.io.storage.HeavyProcessLatch;
|
||||
@@ -171,7 +169,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
@Override
|
||||
public void beforeFileTypesChanged(final FileTypeEvent event) {
|
||||
cleanupProcessedFlag();
|
||||
myTypeToExtensionMap = new HashMap<FileType, Set<String>>();
|
||||
myTypeToExtensionMap = new THashMap<FileType, Set<String>>();
|
||||
for (FileType type : myFileTypeManager.getRegisteredFileTypes()) {
|
||||
myTypeToExtensionMap.put(type, getExtensions(type));
|
||||
}
|
||||
@@ -182,7 +180,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
final Map<FileType, Set<String>> oldExtensions = myTypeToExtensionMap;
|
||||
myTypeToExtensionMap = null;
|
||||
if (oldExtensions != null) {
|
||||
final Map<FileType, Set<String>> newExtensions = new HashMap<FileType, Set<String>>();
|
||||
final Map<FileType, Set<String>> newExtensions = new THashMap<FileType, Set<String>>();
|
||||
for (FileType type : myFileTypeManager.getRegisteredFileTypes()) {
|
||||
newExtensions.put(type, getExtensions(type));
|
||||
}
|
||||
@@ -204,7 +202,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
}
|
||||
|
||||
private Set<String> getExtensions(FileType type) {
|
||||
final Set<String> set = new HashSet<String>();
|
||||
final Set<String> set = new THashSet<String>();
|
||||
for (FileNameMatcher matcher : myFileTypeManager.getAssociations(type)) {
|
||||
set.add(matcher.getPresentableString());
|
||||
}
|
||||
@@ -434,7 +432,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
}
|
||||
|
||||
private static Set<String> readRegisteredIndexNames() {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
final Set<String> result = new THashSet<String>();
|
||||
try {
|
||||
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(getRegisteredIndicesFile())));
|
||||
try {
|
||||
@@ -493,7 +491,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
MemoryIndexStorage<K, ?> storage) throws IOException {
|
||||
final File indexStorageFile = IndexInfrastructure.getInputIndexStorageFile(indexId);
|
||||
final Ref<Boolean> isBufferingMode = new Ref<Boolean>(false);
|
||||
final Map<Integer, Collection<K>> tempMap = new HashMap<Integer, Collection<K>>();
|
||||
final TIntObjectHashMap<Collection<K>> tempMap = new TIntObjectHashMap<Collection<K>>();
|
||||
|
||||
final DataExternalizer<Collection<K>> dataExternalizer = new DataExternalizer<Collection<K>>() {
|
||||
@Override
|
||||
@@ -667,7 +665,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
*/
|
||||
@NotNull
|
||||
public <K> Collection<K> getAllKeys(final ID<K, ?> indexId, @NotNull Project project) {
|
||||
Set<K> allKeys = new HashSet<K>();
|
||||
Set<K> allKeys = new THashSet<K>();
|
||||
processAllKeys(indexId, new CommonProcessors.CollectProcessor<K>(allKeys), project);
|
||||
return allKeys;
|
||||
}
|
||||
@@ -829,7 +827,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
|
||||
@NotNull
|
||||
public <K, V> Collection<VirtualFile> getContainingFiles(final ID<K, V> indexId, @NotNull K dataKey, @NotNull final GlobalSearchScope filter) {
|
||||
final Set<VirtualFile> files = new HashSet<VirtualFile>();
|
||||
final Set<VirtualFile> files = new THashSet<VirtualFile>();
|
||||
processValuesImpl(indexId, dataKey, false, null, new ValueProcessor<V>() {
|
||||
@Override
|
||||
public boolean process(final VirtualFile file, final V value) {
|
||||
@@ -1021,7 +1019,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
|
||||
for (K dataKey : dataKeys) {
|
||||
ProgressManager.checkCanceled();
|
||||
TIntHashSet copy = new TIntHashSet();
|
||||
final TIntHashSet copy = new TIntHashSet();
|
||||
final ValueContainer<V> container = index.getData(dataKey);
|
||||
|
||||
for (final Iterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
|
||||
@@ -1029,12 +1027,27 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
if (valueChecker != null && !valueChecker.value(value)) {
|
||||
continue;
|
||||
}
|
||||
for (final ValueContainer.IntIterator inputIdsIterator = container.getInputIdsIterator(value); inputIdsIterator.hasNext(); ) {
|
||||
final int id = inputIdsIterator.next();
|
||||
if ((mainIntersection == null || mainIntersection.contains(id)) &&
|
||||
(projectFilesFilter == null || projectFilesFilter.contains(id))) {
|
||||
copy.add(id);
|
||||
|
||||
ValueContainer.IntIterator iterator = container.getInputIdsIterator(value);
|
||||
|
||||
if (mainIntersection == null || iterator.size() < mainIntersection.size()) {
|
||||
for (final ValueContainer.IntIterator inputIdsIterator = iterator; inputIdsIterator.hasNext(); ) {
|
||||
final int id = inputIdsIterator.next();
|
||||
if (mainIntersection == null && (projectFilesFilter == null || projectFilesFilter.contains(id)) ||
|
||||
mainIntersection != null && mainIntersection.contains(id)
|
||||
) {
|
||||
copy.add(id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mainIntersection.forEach(new TIntProcedure() {
|
||||
final ValueContainer.IntPredicate predicate = container.getValueAssociationPredicate(value);
|
||||
@Override
|
||||
public boolean execute(int id) {
|
||||
if (predicate.contains(id)) copy.add(id);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1249,7 +1262,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
}
|
||||
|
||||
private Set<Document> getUnsavedOrTransactedDocuments() {
|
||||
final Set<Document> docs = new HashSet<Document>(Arrays.asList(myFileDocumentManager.getUnsavedDocuments()));
|
||||
final Set<Document> docs = new THashSet<Document>(Arrays.asList(myFileDocumentManager.getUnsavedDocuments()));
|
||||
synchronized (myTransactionMap) {
|
||||
docs.addAll(myTransactionMap.keySet());
|
||||
}
|
||||
@@ -2161,7 +2174,7 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<VirtualFile> visitedRoots = new HashSet<VirtualFile>();
|
||||
Set<VirtualFile> visitedRoots = new THashSet<VirtualFile>();
|
||||
for (IndexedRootsProvider provider : Extensions.getExtensions(IndexedRootsProvider.EP_NAME)) {
|
||||
//important not to depend on project here, to support per-project background reindex
|
||||
// each client gives a project to FileBasedIndex
|
||||
|
||||
@@ -31,11 +31,17 @@ public abstract class ValueContainer<Value> {
|
||||
|
||||
int size();
|
||||
}
|
||||
|
||||
static abstract class IntPredicate {
|
||||
abstract boolean contains(int id);
|
||||
}
|
||||
|
||||
public abstract IntIterator getInputIdsIterator(Value value);
|
||||
|
||||
public abstract boolean isAssociated(Value value, int inputId);
|
||||
|
||||
|
||||
public abstract IntPredicate getValueAssociationPredicate(Value value);
|
||||
|
||||
public abstract Iterator<Value> getValueIterator();
|
||||
|
||||
public abstract List<Value> toValueList();
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.containers.EmptyIterator;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import gnu.trove.TIntIterator;
|
||||
import gnu.trove.TObjectObjectProcedure;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -29,7 +31,6 @@ import java.util.*;
|
||||
*/
|
||||
class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implements Cloneable{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl");
|
||||
|
||||
private THashMap<Value, Object> myInputIdMapping;
|
||||
|
||||
public ValueContainerImpl() {
|
||||
@@ -117,6 +118,10 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public Iterator<Value> getValueIterator() {
|
||||
if (myInputIdMapping.size() == 0) {
|
||||
return EmptyIterator.getInstance();
|
||||
}
|
||||
|
||||
final Set<Value> values = Collections.unmodifiableSet(myInputIdMapping.keySet());
|
||||
return new Iterator<Value>() {
|
||||
final Iterator<Value> iterator = values.iterator();
|
||||
@@ -161,6 +166,28 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntPredicate getValueAssociationPredicate(Value value) {
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
if (input == null) return EMPTY_PREDICATE;
|
||||
if (input instanceof Integer) {
|
||||
return new IntPredicate() {
|
||||
final int myId = (Integer)input;
|
||||
@Override
|
||||
public boolean contains(int id) {
|
||||
return id == myId;
|
||||
}
|
||||
};
|
||||
}
|
||||
return new IntPredicate() {
|
||||
final TIntHashSet mySet = (TIntHashSet)input;
|
||||
@Override
|
||||
boolean contains(int id) {
|
||||
return mySet.contains(id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntIterator getInputIdsIterator(Value value) {
|
||||
value = maskNull(value);
|
||||
@@ -266,15 +293,26 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
return null;
|
||||
}
|
||||
final THashMap<Value, Object> cloned = map.clone();
|
||||
for (Value key : cloned.keySet()) {
|
||||
final Object val = cloned.get(key);
|
||||
if (val instanceof TIntHashSet) {
|
||||
cloned.put(key, ((TIntHashSet)val).clone());
|
||||
cloned.forEachEntry(new TObjectObjectProcedure<Value, Object>() {
|
||||
@Override
|
||||
public boolean execute(Value key, Object val) {
|
||||
if (val instanceof TIntHashSet) {
|
||||
cloned.put(key, ((TIntHashSet)val).clone());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return cloned;
|
||||
}
|
||||
|
||||
private static final IntPredicate EMPTY_PREDICATE = new IntPredicate() {
|
||||
@Override
|
||||
public boolean contains(int id) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private static class IdSet extends TIntHashSet {
|
||||
|
||||
private IdSet(final int initialCapacity, final float loadFactor) {
|
||||
|
||||
Reference in New Issue
Block a user