[vcs-log] extract IndexDataGetter class, responsible for getting various data available from indexes

This commit is contained in:
Julia Beliaeva
2017-01-31 23:54:52 +03:00
parent af38e96e7b
commit 71c109b2e5
9 changed files with 133 additions and 69 deletions
@@ -17,6 +17,7 @@ import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.CommitId;
import com.intellij.vcs.log.VcsLogProvider;
import com.intellij.vcs.log.VcsShortCommitDetails;
import com.intellij.vcs.log.data.index.IndexDataGetter;
import com.intellij.vcs.log.data.index.IndexedDetails;
import com.intellij.vcs.log.data.index.VcsLogIndex;
import com.intellij.vcs.log.util.SequentialLimitedLifoExecutor;
@@ -223,7 +224,13 @@ abstract class AbstractDataGetter<T extends VcsShortCommitDetails> implements Di
// fill the cache with temporary "Loading" values to avoid producing queries for each commit that has not been cached yet,
// even if it will be loaded within a previous query
if (!myCache.isKeyCached(commitId)) {
myCache.put(commitId, (T)new IndexedDetails(myIndex, myStorage, commitId, taskNumber));
IndexDataGetter dataGetter = myIndex.getDataGetter();
if (dataGetter != null) {
myCache.put(commitId, (T)new IndexedDetails(dataGetter, myStorage, commitId, taskNumber));
}
else {
myCache.put(commitId, (T)new LoadingDetails(() -> myStorage.getCommitId(commitId), taskNumber));
}
}
}
@@ -15,9 +15,9 @@
*/
package com.intellij.vcs.log.data;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.VcsLogDetailsFilter;
import com.intellij.vcs.log.data.index.IndexDataGetter;
import com.intellij.vcs.log.data.index.VcsLogIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,15 +55,9 @@ public class EmptyIndex implements VcsLogIndex {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public Set<FilePath> getFileNames(@NotNull FilePath path, int commit) {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public String getFullMessage(int index) {
public IndexDataGetter getDataGetter() {
return null;
}
@@ -0,0 +1,72 @@
/*
* Copyright 2000-2017 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.vcs.log.data.index;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.indexing.StorageException;
import com.intellij.vcs.log.impl.FatalErrorHandler;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
public class IndexDataGetter {
@NotNull private final Project myProject;
@NotNull private final Set<VirtualFile> myRoots;
@NotNull private final VcsLogPersistentIndex.IndexStorage myIndexStorage;
@NotNull private final FatalErrorHandler myFatalErrorsConsumer;
public IndexDataGetter(@NotNull Project project,
@NotNull Set<VirtualFile> roots,
@NotNull VcsLogPersistentIndex.IndexStorage storage,
@NotNull FatalErrorHandler fatalErrorsConsumer) {
myProject = project;
myRoots = roots;
myIndexStorage = storage;
myFatalErrorsConsumer = fatalErrorsConsumer;
}
@Nullable
public String getFullMessage(int index) {
try {
return myIndexStorage.messages.get(index);
}
catch (IOException e) {
myFatalErrorsConsumer.consume(this, e);
}
return null;
}
@NotNull
public Set<FilePath> getFileNames(@NotNull FilePath path, int commit) {
VirtualFile root = VcsUtil.getVcsRootFor(myProject, path);
if (myRoots.contains(root)) {
try {
return myIndexStorage.paths.getFileNames(path, commit);
}
catch (IOException | StorageException e) {
myFatalErrorsConsumer.consume(this, e);
}
}
return Collections.emptySet();
}
}
@@ -20,22 +20,22 @@ import com.intellij.vcs.log.data.VcsLogStorage;
import org.jetbrains.annotations.NotNull;
public class IndexedDetails extends LoadingDetails {
@NotNull private final VcsLogIndex myIndex;
@NotNull private final IndexDataGetter myDataGetter;
private final int myCommitIndex;
public IndexedDetails(@NotNull VcsLogIndex index,
public IndexedDetails(@NotNull IndexDataGetter dataGetter,
@NotNull VcsLogStorage storage,
int commitIndex,
long loadingTaskIndex) {
super(() -> storage.getCommitId(commitIndex), loadingTaskIndex);
myIndex = index;
myDataGetter = dataGetter;
myCommitIndex = commitIndex;
}
@NotNull
@Override
public String getFullMessage() {
String message = myIndex.getFullMessage(myCommitIndex);
String message = myDataGetter.getFullMessage(myCommitIndex);
if (message != null) return message;
return super.getFullMessage();
}
@@ -43,7 +43,7 @@ public class IndexedDetails extends LoadingDetails {
@NotNull
@Override
public String getSubject() {
String message = myIndex.getFullMessage(myCommitIndex);
String message = myDataGetter.getFullMessage(myCommitIndex);
if (message != null) {
return getSubject(message);
}
@@ -15,7 +15,6 @@
*/
package com.intellij.vcs.log.data.index;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.VcsLogDetailsFilter;
import org.jetbrains.annotations.NotNull;
@@ -39,9 +38,7 @@ public interface VcsLogIndex {
Set<Integer> filter(@NotNull List<VcsLogDetailsFilter> detailsFilters);
@Nullable
String getFullMessage(int index);
Set<FilePath> getFileNames(@NotNull FilePath path, int commit);
IndexDataGetter getDataGetter();
void markCorrupted();
@@ -41,14 +41,16 @@ import com.intellij.vcs.log.util.PersistentSet;
import com.intellij.vcs.log.util.PersistentSetImpl;
import com.intellij.vcs.log.util.StopWatch;
import com.intellij.vcs.log.util.TroveUtil;
import com.intellij.vcsUtil.VcsUtil;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
@@ -67,7 +69,8 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
@NotNull private final VcsUserRegistryImpl myUserRegistry;
@NotNull private final Set<VirtualFile> myRoots;
@Nullable private final MyIndexStorage myIndexStorage;
@Nullable private final IndexStorage myIndexStorage;
@Nullable private final IndexDataGetter myDataGetter;
@NotNull private final SingleTaskController<IndexingRequest, Void> mySingleTaskController = new MySingleTaskController();
@NotNull private final Map<VirtualFile, AtomicInteger> myNumberOfTasks = ContainerUtil.newHashMap();
@@ -98,6 +101,12 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(myProject, VcsUserRegistry.class);
myIndexStorage = createIndexStorage(fatalErrorsConsumer, calcLogId(myProject, providers));
if (myIndexStorage != null) {
myDataGetter = new IndexDataGetter(myProject, myRoots, myIndexStorage, myFatalErrorsConsumer);
}
else {
myDataGetter = null;
}
for (VirtualFile root : myRoots) {
myNumberOfTasks.put(root, new AtomicInteger());
@@ -106,10 +115,10 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
Disposer.register(disposableParent, this);
}
protected MyIndexStorage createIndexStorage(@NotNull FatalErrorHandler fatalErrorHandler, @NotNull String logId) {
protected IndexStorage createIndexStorage(@NotNull FatalErrorHandler fatalErrorHandler, @NotNull String logId) {
try {
return IOUtil.openCleanOrResetBroken(() -> new MyIndexStorage(logId, myUserRegistry, myRoots, fatalErrorHandler, this),
() -> MyIndexStorage.cleanup(logId));
return IOUtil.openCleanOrResetBroken(() -> new IndexStorage(logId, myUserRegistry, myRoots, fatalErrorHandler, this),
() -> IndexStorage.cleanup(logId));
}
catch (IOException e) {
myFatalErrorsConsumer.consume(this, e);
@@ -359,32 +368,9 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
@Nullable
@Override
public String getFullMessage(int index) {
if (myIndexStorage != null) {
try {
return myIndexStorage.messages.get(index);
}
catch (IOException e) {
myFatalErrorsConsumer.consume(this, e);
}
}
return null;
}
@NotNull
@Override
public Set<FilePath> getFileNames(@NotNull FilePath path, int commit) {
VirtualFile root = VcsUtil.getVcsRootFor(myProject, path);
if (myIndexStorage != null && myRoots.contains(root)) {
try {
return myIndexStorage.paths.getFileNames(path, commit);
}
catch (IOException | StorageException e) {
myFatalErrorsConsumer.consume(this, e);
}
}
return Collections.emptySet();
public IndexDataGetter getDataGetter() {
if (myIndexStorage == null) return null;
return myDataGetter;
}
@Override
@@ -401,22 +387,22 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
public void dispose() {
}
private static class MyIndexStorage {
static class IndexStorage {
private static final String INPUTS = "inputs";
private static final String COMMITS = "commits";
private static final String MESSAGES = "messages";
private static final int MESSAGES_VERSION = 0;
@NotNull private final PersistentSet<Integer> commits;
@NotNull private final PersistentMap<Integer, String> messages;
@NotNull private final VcsLogMessagesTrigramIndex trigrams;
@NotNull private final VcsLogUserIndex users;
@NotNull private final VcsLogPathsIndex paths;
private static final String INPUTS = "inputs";
@NotNull public final PersistentSet<Integer> commits;
@NotNull public final PersistentMap<Integer, String> messages;
@NotNull public final VcsLogMessagesTrigramIndex trigrams;
@NotNull public final VcsLogUserIndex users;
@NotNull public final VcsLogPathsIndex paths;
public MyIndexStorage(@NotNull String logId,
@NotNull VcsUserRegistryImpl userRegistry,
@NotNull Set<VirtualFile> roots,
@NotNull FatalErrorHandler fatalErrorHandler,
@NotNull Disposable parentDisposable)
public IndexStorage(@NotNull String logId,
@NotNull VcsUserRegistryImpl userRegistry,
@NotNull Set<VirtualFile> roots,
@NotNull FatalErrorHandler fatalErrorHandler,
@NotNull Disposable parentDisposable)
throws IOException {
Disposable disposable = Disposer.newDisposable();
Disposer.register(parentDisposable, disposable);
@@ -70,6 +70,7 @@ public class ShowHistoryAction extends DumbAwareAction {
VcsLogData dataManager = VcsProjectLog.getInstance(project).getDataManager();
presentation.setEnabledAndVisible(root != null &&
dataManager != null &&
dataManager.getRoots().contains(root));
dataManager.getRoots().contains(root) &&
dataManager.getIndex().getDataGetter() != null);
}
}
@@ -35,6 +35,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.data.LoadingDetails;
import com.intellij.vcs.log.data.VcsLogData;
import com.intellij.vcs.log.data.index.IndexDataGetter;
import com.intellij.vcs.log.impl.MainVcsLogUiProperties;
import com.intellij.vcs.log.ui.VcsLogActionPlaces;
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys;
@@ -62,6 +63,7 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
@NotNull private final FileHistoryUi myUi;
@NotNull private List<Change> mySelectedChanges = Collections.emptyList();
@NotNull private IndexDataGetter myIndexDataGetter;
public FileHistoryPanel(@NotNull FileHistoryUi ui,
@NotNull VcsLogData logData,
@@ -69,6 +71,7 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
@NotNull FilePath filePath) {
myUi = ui;
myLogData = logData;
myIndexDataGetter = ObjectUtils.assertNotNull(logData.getIndex().getDataGetter());
myFilePath = filePath;
myGraphTable = new VcsLogGraphTable(myUi, logData, visiblePack) {
@Override
@@ -165,8 +168,8 @@ public class FileHistoryPanel extends JPanel implements DataProvider, Disposable
@NotNull
private List<Change> collectRelevantChanges(@NotNull VcsFullCommitDetails details) {
Set<FilePath> fileNames =
myLogData.getIndex().getFileNames(myFilePath, myLogData.getStorage().getCommitIndex(details.getId(), details.getRoot()));
Set<FilePath> fileNames = myIndexDataGetter.getFileNames(myFilePath,
myLogData.getStorage().getCommitIndex(details.getId(), details.getRoot()));
if (myFilePath.isDirectory()) {
return ContainerUtil.filter(details.getChanges(), change -> affectsDirectories(change, fileNames));
}
@@ -23,6 +23,7 @@ import com.intellij.vcs.log.VcsCommitMetadata;
import com.intellij.vcs.log.VcsLogUserFilter;
import com.intellij.vcs.log.VcsUser;
import com.intellij.vcs.log.VcsUserRegistry;
import com.intellij.vcs.log.data.index.IndexDataGetter;
import com.intellij.vcs.log.data.index.IndexedDetails;
import com.intellij.vcs.log.data.index.VcsLogIndex;
import com.intellij.vcs.log.impl.VcsLogUtil;
@@ -93,10 +94,13 @@ public class IndexSpeedSearch extends VcsLogSpeedSearch {
@Nullable
private String getCommitSubject(@NotNull Integer row) {
Integer id = myComponent.getModel().getIdAtRow(row);
String message = myIndex.getFullMessage(id);
if (message == null) return super.getElementText(row);
return IndexedDetails.getSubject(message);
IndexDataGetter dataGetter = myIndex.getDataGetter();
if (dataGetter != null) {
Integer id = myComponent.getModel().getIdAtRow(row);
String message = dataGetter.getFullMessage(id);
if (message != null) return IndexedDetails.getSubject(message);
}
return super.getElementText(row);
}
@Override