mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log] ensure that persistent storages are closed if exception occurs in VcsLogFullDetailsIndex constructor
Persistent storages are registered in the FilePageCache#registerPagedFileStorage on creation and deregistered on close, so if the storage is not closed properly, a new instance with the same path can't be created later. IDEA-330343, EA-933249 GitOrigin-RevId: fbec9dc8a25ebbf52b8cc7bc203a55c723f18121
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b31ab28504
commit
7da501ece2
@@ -7,6 +7,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.indexing.impl.IndexStorage;
|
||||
import com.intellij.util.indexing.impl.MapIndexStorage;
|
||||
@@ -128,6 +129,18 @@ public class VcsLogFullDetailsIndex<T, D> implements Disposable {
|
||||
if (myDisposed) throw new ProcessCanceledException();
|
||||
}
|
||||
|
||||
protected static void catchAndWarn(@NotNull Logger logger, @NotNull ThrowableRunnable<IOException> runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
logger.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MyMapReduceIndex<T, D> extends MapReduceIndex<Integer, T, D> {
|
||||
private final @NotNull VcsLogErrorHandler myErrorHandler;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.intellij.vcs.log.data.index;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -39,7 +40,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
final class VcsLogPathsIndex extends VcsLogFullDetailsIndex<List<ChangeKind>, CompressedDetails> {
|
||||
public final class VcsLogPathsIndex extends VcsLogFullDetailsIndex<List<ChangeKind>, CompressedDetails> {
|
||||
private static final Logger LOG = Logger.getInstance(VcsLogPathsIndex.class);
|
||||
public static final String PATHS = "paths";
|
||||
public static final String INDEX_PATHS_IDS = "paths-ids";
|
||||
@@ -95,17 +96,6 @@ final class VcsLogPathsIndex extends VcsLogFullDetailsIndex<List<ChangeKind>, Co
|
||||
myPathsIndexer.myPathsEnumerator.force();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
try {
|
||||
myPathsIndexer.myPathsEnumerator.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null,_ -> null; !null,_ -> !null")
|
||||
static @Nullable FilePath toFilePath(@Nullable LightFilePath lightFilePath, boolean isDirectory) {
|
||||
if (lightFilePath == null) return null;
|
||||
@@ -117,11 +107,20 @@ final class VcsLogPathsIndex extends VcsLogFullDetailsIndex<List<ChangeKind>, Co
|
||||
@NotNull PersistentHashMap<int[], int[]> renamesMap,
|
||||
boolean useDurableEnumerator, @NotNull VcsLogErrorHandler errorHandler,
|
||||
@NotNull Disposable disposableParent) throws IOException {
|
||||
DurableDataEnumerator<LightFilePath> pathsEnumerator = createPathsEnumerator(roots, storageId, storageLockContext,
|
||||
useDurableEnumerator);
|
||||
PathIndexer pathsIndex = new PathIndexer(storage, pathsEnumerator, renamesMap,
|
||||
e -> errorHandler.handleError(VcsLogErrorHandler.Source.Index, e));
|
||||
return new VcsLogPathsIndex(storageId, storageLockContext, pathsIndex, errorHandler, disposableParent);
|
||||
Disposable disposable = Disposer.newDisposable(disposableParent);
|
||||
try {
|
||||
DurableDataEnumerator<LightFilePath> pathsEnumerator = createPathsEnumerator(roots, storageId, storageLockContext,
|
||||
useDurableEnumerator);
|
||||
Disposer.register(disposable, () -> catchAndWarn(LOG, pathsEnumerator::close));
|
||||
|
||||
PathIndexer pathsIndex = new PathIndexer(storage, pathsEnumerator, renamesMap,
|
||||
e -> errorHandler.handleError(VcsLogErrorHandler.Source.Index, e));
|
||||
return new VcsLogPathsIndex(storageId, storageLockContext, pathsIndex, errorHandler, disposable);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Disposer.dispose(disposable);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
static final class PathIndexer implements DataIndexer<Integer, List<ChangeKind>, CompressedDetails> {
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.intellij.vcs.log.data.index;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.util.indexing.DataIndexer;
|
||||
import com.intellij.util.indexing.StorageException;
|
||||
import com.intellij.util.indexing.impl.MapReduceIndex;
|
||||
import com.intellij.util.indexing.impl.forward.KeyCollectionForwardIndexAccessor;
|
||||
import com.intellij.util.indexing.impl.forward.PersistentMapBasedForwardIndex;
|
||||
import com.intellij.util.io.IntCollectionDataExternalizer;
|
||||
@@ -112,27 +112,27 @@ final class VcsLogUserIndex extends VcsLogFullDetailsIndex<Void, VcsShortCommitD
|
||||
myUserIndexer.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
try {
|
||||
myUserIndexer.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
static @NotNull VcsLogUserIndex create(@NotNull StorageId.Directory storageId,
|
||||
@Nullable StorageLockContext storageLockContext,
|
||||
@NotNull VcsUserRegistry userRegistry,
|
||||
@NotNull VcsLogErrorHandler errorHandler,
|
||||
@NotNull Disposable disposableParent) throws IOException {
|
||||
PersistentMapBasedForwardIndex forwardIndex = new PersistentMapBasedForwardIndex(storageId.getStorageFile(USERS + ".idx"),
|
||||
true, false, storageLockContext);
|
||||
PersistentEnumerator<VcsUser> enumerator = createUserEnumerator(storageId, storageLockContext, userRegistry);
|
||||
UserIndexer userIndexer = new UserIndexer(enumerator, e -> errorHandler.handleError(VcsLogErrorHandler.Source.Index, e));
|
||||
return new VcsLogUserIndex(storageId, userIndexer, forwardIndex, storageLockContext, errorHandler, disposableParent);
|
||||
Disposable disposable = Disposer.newDisposable(disposableParent);
|
||||
try {
|
||||
PersistentMapBasedForwardIndex forwardIndex = new PersistentMapBasedForwardIndex(storageId.getStorageFile(USERS + ".idx"),
|
||||
true, false, storageLockContext);
|
||||
Disposer.register(disposable, () -> catchAndWarn(LOG, forwardIndex::close));
|
||||
|
||||
PersistentEnumerator<VcsUser> userEnumerator = createUserEnumerator(storageId, storageLockContext, userRegistry);
|
||||
Disposer.register(disposable, () -> catchAndWarn(LOG, userEnumerator::close));
|
||||
|
||||
UserIndexer userIndexer = new UserIndexer(userEnumerator, e -> errorHandler.handleError(VcsLogErrorHandler.Source.Index, e));
|
||||
return new VcsLogUserIndex(storageId, userIndexer, forwardIndex, storageLockContext, errorHandler, disposable);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Disposer.dispose(disposable);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UserIndexer implements DataIndexer<Integer, Void, VcsShortCommitDetails> {
|
||||
|
||||
Reference in New Issue
Block a user