document leak fixed

This commit is contained in:
Alexey Kudravtsev
2011-02-22 20:47:48 +03:00
parent 12eae7ea00
commit 26a7a211fe
4 changed files with 78 additions and 71 deletions
@@ -78,6 +78,8 @@ public class ID<K, V> {
}
int n = ourNameToIdRegistry.size() + 1;
assert n <= Short.MAX_VALUE : "Number of indices exceeded";
ourNameToIdRegistry.put(name, n);
writeEnumFile();
@@ -101,14 +101,7 @@ public class FileBasedIndex implements ApplicationComponent {
private final Set<ID<?, ?>> myNotRequiringContentIndices = new HashSet<ID<?, ?>>();
private final Set<FileType> myNoLimitCheckTypes = new HashSet<FileType>();
private final PerIndexDocumentMap<Long> myLastIndexedDocStamps = new PerIndexDocumentMap<Long>() {
@NotNull
@Override
protected Long createDefault(@NotNull Document document) {
return 0L;
}
};
private final PerIndexDocumentVersionMap myLastIndexedDocStamps = new PerIndexDocumentVersionMap();
private final ChangedFilesCollector myChangedFilesCollector;
private final List<IndexableFileSet> myIndexableSets = ContainerUtil.createEmptyCOWList();
@@ -354,7 +347,6 @@ public class FileBasedIndex implements ApplicationComponent {
* @param isCurrentVersionCorrupted
*/
private <K, V> boolean registerIndexer(final FileBasedIndexExtension<K, V> extension, final boolean isCurrentVersionCorrupted) throws IOException {
boolean versionChanged = false;
final ID<K, V> name = extension.getName();
final int version = extension.getVersion();
if (!extension.dependsOnFileContent()) {
@@ -363,6 +355,7 @@ public class FileBasedIndex implements ApplicationComponent {
myIndexIdToVersionMap.put(name, version);
final File versionFile = IndexInfrastructure.getVersionFile(name);
final boolean versionFileExisted = versionFile.exists();
boolean versionChanged = false;
if (isCurrentVersionCorrupted || IndexInfrastructure.versionDiffers(versionFile, version)) {
if (!isCurrentVersionCorrupted && versionFileExisted) {
versionChanged = true;
@@ -1181,7 +1174,7 @@ public class FileBasedIndex implements ApplicationComponent {
}
final long currentDocStamp = content.getModificationStamp();
if (currentDocStamp != myLastIndexedDocStamps.getAndSet(document, requestedIndexId, currentDocStamp).longValue()) {
if (currentDocStamp != myLastIndexedDocStamps.getAndSet(document, requestedIndexId, currentDocStamp)) {
final Ref<StorageException> exRef = new Ref<StorageException>(null);
ProgressManager.getInstance().executeNonCancelableSection(new Runnable() {
public void run() {
@@ -1770,10 +1763,10 @@ public class FileBasedIndex implements ApplicationComponent {
if (file instanceof VirtualFileWithId) {
try {
boolean oldStuff = true;
if (file instanceof NewVirtualFile) {
file.putUserData(NewVirtualFile.FILE_TYPE_KEY, file.getFileType());
}
boolean oldStuff = true;
if (!isTooLarge(file)) {
for (ID<?, ?> indexId : myIndices.keySet()) {
try {
@@ -1,60 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.indexing;
import com.intellij.openapi.editor.Document;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.ConcurrentWeakFactoryMap;
import java.util.Map;
/**
* @author Dmitry Avdeev
* @author peter
*/
public abstract class PerIndexDocumentMap<T> {
private final Map<Document, Map<ID, T>> myVersions = new ConcurrentWeakFactoryMap<Document, Map<ID, T>>() {
protected Map<ID, T> create(final Document document) {
return new ConcurrentFactoryMap<ID,T>() {
protected T create(ID key) {
return createDefault(document);
}
};
}
};
public T get(Document document, ID indexId) {
return myVersions.get(document).get(indexId);
}
public void put(Document document, ID indexId, T value) {
myVersions.get(document).put(indexId, value);
}
public synchronized T getAndSet(Document document, ID indexId, T value) {
T old = get(document, indexId);
put(document, indexId, value);
return old;
}
public void clear() {
myVersions.clear();
}
protected abstract T createDefault(Document document);
}
@@ -0,0 +1,72 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.indexing;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderEx;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Dmitry Avdeev
* @author peter
*/
public class PerIndexDocumentVersionMap {
private volatile int mapVersion;
private static class IdVersionInfo {
private final ID<?,?> id;
private int mapVersion;
private long docVersion;
private IdVersionInfo(@NotNull ID<?, ?> id, long docVersion, int mapVersion) {
this.docVersion = docVersion;
this.mapVersion = mapVersion;
this.id = id;
}
}
private static final Key<List<IdVersionInfo>> KEY = Key.create("UnsavedDocIdVersionInfo");
public long getAndSet(@NotNull Document document, @NotNull ID<?, ?> indexId, long value) {
List<IdVersionInfo> list = document.getUserData(KEY);
if (list == null) {
list = ((UserDataHolderEx)document).putUserDataIfAbsent(KEY, new ArrayList<IdVersionInfo>());
}
synchronized (list) {
for (IdVersionInfo info : list) {
if (info.id == indexId) {
long old = info.docVersion;
if (info.mapVersion != mapVersion) {
old = 0;
info.mapVersion = mapVersion;
}
info.docVersion = value;
return old;
}
}
list.add(new IdVersionInfo(indexId, value, mapVersion));
return 0;
}
}
public void clear() {
mapVersion++;
}
}