diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogFullDetailsIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogFullDetailsIndex.java index 24659ac7a733..5b19a551225f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogFullDetailsIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogFullDetailsIndex.java @@ -20,7 +20,10 @@ import com.intellij.openapi.util.Disposer; import com.intellij.util.Consumer; import com.intellij.util.PathUtilRt; import com.intellij.util.indexing.*; -import com.intellij.util.io.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorIntegerDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.io.PersistentHashMap; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.impl.FatalErrorHandler; import com.intellij.vcs.log.util.PersistentUtil; @@ -36,7 +39,6 @@ import java.util.function.ObjIntConsumer; public class VcsLogFullDetailsIndex implements Disposable { @NotNull protected static final String INDEX = "index-"; - @NotNull protected static final String INDEX_INPUTS = "index-inputs-"; @NotNull protected final MyMapReduceIndex myMapReduceIndex; @NotNull private final ID myID; @NotNull private final String myLogId; @@ -58,13 +60,7 @@ public class VcsLogFullDetailsIndex implements Disposable { myIndexer = indexer; myFatalErrorHandler = fatalErrorHandler; - MyMapReduceIndex result = IOUtil.openCleanOrResetBroken(() -> new MyMapReduceIndex(myIndexer, externalizer, version), - () -> { - IOUtil.deleteAllFilesStartingWith(getStorageFile(version)); - IOUtil.deleteAllFilesStartingWith(getInputsStorageFile(version)); - }); - if (result == null) throw new IOException("Can not create " + myName + " index for " + myLogId); - myMapReduceIndex = result; + myMapReduceIndex = new MyMapReduceIndex(myIndexer, externalizer, version); Disposer.register(disposableParent, this); } @@ -120,32 +116,16 @@ public class VcsLogFullDetailsIndex implements Disposable { myMapReduceIndex.flush(); } - public boolean isIndexed(int commit) throws IOException { - return myMapReduceIndex.isIndexed(commit); - } - @Override public void dispose() { myMapReduceIndex.dispose(); } - protected void onNotIndexableCommit(int commit) throws StorageException { - } - - public void markCorrupted() { - myMapReduceIndex.markCorrupted(); - } - @NotNull - private File getStorageFile(int version) { + public File getStorageFile(int version) { return getStorageFile(INDEX + myName, myLogId, version); } - @NotNull - private File getInputsStorageFile(int version) { - return PersistentUtil.getStorageFile(INDEX_INPUTS + myName, myLogId, version); - } - @NotNull public static File getStorageFile(@NotNull String kind, @NotNull String id, int version) { File subdir = new File(PersistentUtil.LOG_CACHE, kind); @@ -153,11 +133,6 @@ public class VcsLogFullDetailsIndex implements Disposable { return new File(subdir, safeLogId + "." + version); } - @Nullable - protected Collection getKeysForCommit(int commit) throws IOException { - return myMapReduceIndex.getInputsIndex().get(commit); - } - private class MyMapReduceIndex extends MapReduceIndex { public MyMapReduceIndex(@NotNull DataIndexer indexer, @@ -169,33 +144,9 @@ public class VcsLogFullDetailsIndex implements Disposable { externalizer, 5000)); } - @NotNull - public PersistentHashMap> getInputsIndex() { - return myInputsIndex; - } - - public boolean isIndexed(int commitId) throws IOException { - return myInputsIndex.containsMapping(commitId); - } - @Override protected PersistentHashMap> createInputsIndex() throws IOException { - IndexExtension extension = getExtension(); - return new PersistentHashMap<>(getInputsStorageFile(extension.getVersion()), - EnumeratorIntegerDescriptor.INSTANCE, - new InputIndexDataExternalizer<>(extension.getKeyDescriptor(), myID)); - } - - @Override - protected void updateWithMap(int inputId, @NotNull UpdateData updateData) throws StorageException { - if (((SimpleUpdateData)updateData).getNewData().isEmpty()) { - onNotIndexableCommit(inputId); - } - super.updateWithMap(inputId, updateData); - } - - public void markCorrupted() { - myInputsIndex.markCorrupted(); + return null; } @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogMessagesTrigramIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogMessagesTrigramIndex.java index 03a80d3cf63b..9872ab2e3153 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogMessagesTrigramIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogMessagesTrigramIndex.java @@ -16,40 +16,38 @@ package com.intellij.vcs.log.data.index; import com.intellij.openapi.Disposable; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.TrigramBuilder; import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.ScalarIndexExtension; import com.intellij.util.indexing.StorageException; import com.intellij.util.indexing.ValueContainer; -import com.intellij.util.io.EnumeratorIntegerDescriptor; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.impl.FatalErrorHandler; -import com.intellij.vcs.log.util.PersistentSet; -import com.intellij.vcs.log.util.PersistentUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.Collections; import java.util.Map; -public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex { - private static final Logger LOG = Logger.getInstance(VcsLogMessagesTrigramIndex.class); - private static final String TRIGRAMS = "trigrams"; +import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion; - @NotNull private final PersistentSet myNoTrigramsCommits; +public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex { + private static final String TRIGRAMS = "trigrams"; public VcsLogMessagesTrigramIndex(@NotNull String logId, @NotNull FatalErrorHandler fatalErrorHandler, @NotNull Disposable disposableParent) throws IOException { - super(logId, TRIGRAMS, VcsLogPersistentIndex.getVersion(), new TrigramMessageIndexer(), ScalarIndexExtension.VOID_DATA_EXTERNALIZER, + super(logId, TRIGRAMS, getVersion(), new TrigramMessageIndexer(), ScalarIndexExtension.VOID_DATA_EXTERNALIZER, fatalErrorHandler, disposableParent); + } - myNoTrigramsCommits = - PersistentUtil.createPersistentSet(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + TRIGRAMS, logId, - VcsLogPersistentIndex.getVersion()); + @NotNull + public static Collection getStorageFiles(@NotNull String logId) { + return Collections.singletonList(getStorageFile(TRIGRAMS, logId, getVersion())); } @Nullable @@ -62,64 +60,6 @@ public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex { return getCommitsWithAllKeys(trigramProcessor.map.keySet()); } - @Override - protected void onNotIndexableCommit(int commit) throws StorageException { - try { - myNoTrigramsCommits.put(commit); - } - catch (IOException e) { - throw new StorageException(e); - } - } - - @Override - public boolean isIndexed(int commit) throws IOException { - return super.isIndexed(commit) || myNoTrigramsCommits.contains(commit); - } - - @Override - public void flush() throws StorageException { - super.flush(); - myNoTrigramsCommits.flush(); - } - - @Override - public void dispose() { - super.dispose(); - try { - myNoTrigramsCommits.close(); - } - catch (IOException e) { - LOG.warn(e); - } - } - - @Override - public void markCorrupted() { - super.markCorrupted(); - myNoTrigramsCommits.markCorrupted(); - } - - @NotNull - public String getTrigramInfo(int commit) throws IOException { - if (myNoTrigramsCommits.contains(commit)) { - return "No trigrams"; - } - - Collection keys = getKeysForCommit(commit); - assert keys != null; - - StringBuilder builder = new StringBuilder(); - for (Integer key : keys) { - builder.append((char)(key >> 16)); - builder.append((char)((key >> 8) % 256)); - builder.append((char)(key % 256)); - builder.append(" "); - } - - return builder.toString(); - } - public static class TrigramMessageIndexer implements DataIndexer { @NotNull @Override diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPathsIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPathsIndex.java index 76c0dc173fd8..cd254b2b7c81 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPathsIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPathsIndex.java @@ -33,7 +33,6 @@ import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; import com.intellij.vcs.log.VcsFullCommitDetails; import com.intellij.vcs.log.impl.FatalErrorHandler; import com.intellij.vcs.log.impl.VcsChangesLazilyParsedDetails; -import com.intellij.vcs.log.util.PersistentSet; import com.intellij.vcs.log.util.PersistentUtil; import gnu.trove.THashMap; import gnu.trove.TIntHashSet; @@ -43,72 +42,50 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Set; import static com.intellij.util.containers.ContainerUtil.newTroveSet; +import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion; public class VcsLogPathsIndex extends VcsLogFullDetailsIndex { private static final Logger LOG = Logger.getInstance(VcsLogPathsIndex.class); - private static final String NAME = "paths"; + private static final String PATHS = "paths"; + private static final String INDEX_PATHS_IDS = "index-paths-ids"; - @NotNull private final PersistentSet myEmptyCommits; @NotNull private final PathsIndexer myPathsIndexer; public VcsLogPathsIndex(@NotNull String logId, @NotNull Set roots, @NotNull FatalErrorHandler fatalErrorHandler, @NotNull Disposable disposableParent) throws IOException { - super(logId, NAME, VcsLogPersistentIndex.getVersion(), new PathsIndexer(createPathsEnumerator(logId), roots), + super(logId, PATHS, getVersion(), new PathsIndexer(createPathsEnumerator(logId), roots), new NullableIntKeyDescriptor(), fatalErrorHandler, disposableParent); - myEmptyCommits = PersistentUtil.createPersistentSet(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + NAME, logId, - VcsLogPersistentIndex.getVersion()); myPathsIndexer = (PathsIndexer)myIndexer; - myPathsIndexer.setFatalErrorConsumer(e -> { - fatalErrorHandler.consume(this, e); - markCorrupted(); - }); + myPathsIndexer.setFatalErrorConsumer(e -> fatalErrorHandler.consume(this, e)); } @NotNull private static PersistentEnumeratorBase createPathsEnumerator(@NotNull String logId) throws IOException { - int version = VcsLogPersistentIndex.getVersion(); - final File storageFile = PersistentUtil.getStorageFile("index-paths-ids", logId, version); + File storageFile = PersistentUtil.getStorageFile(INDEX_PATHS_IDS, logId, getVersion()); - PersistentBTreeEnumerator enumerator = IOUtil.openCleanOrResetBroken( - () -> new PersistentBTreeEnumerator<>(storageFile, SystemInfo.isFileSystemCaseSensitive ? EnumeratorStringDescriptor.INSTANCE - : new ToLowerCaseStringDescriptor(), - Page.PAGE_SIZE, null, version), - () -> { - IOUtil.deleteAllFilesStartingWith(getStorageFile(INDEX + NAME, logId, version)); - IOUtil.deleteAllFilesStartingWith(getStorageFile(INDEX_INPUTS + NAME, logId, version)); - IOUtil.deleteAllFilesStartingWith(storageFile); - }); - if (enumerator == null) throw new IOException("Can not create enumerator " + NAME + " for " + logId); - return enumerator; + return new PersistentBTreeEnumerator<>(storageFile, SystemInfo.isFileSystemCaseSensitive ? EnumeratorStringDescriptor.INSTANCE + : new ToLowerCaseStringDescriptor(), + Page.PAGE_SIZE, null, getVersion()); } - @Override - protected void onNotIndexableCommit(int commit) throws StorageException { - try { - myEmptyCommits.put(commit); - } - catch (IOException e) { - throw new StorageException(e); - } - } - - @Override - public boolean isIndexed(int commit) throws IOException { - return super.isIndexed(commit) || myEmptyCommits.contains(commit); + @NotNull + public static Collection getStorageFiles(@NotNull String logId) { + return Arrays.asList(PersistentUtil.getStorageFile(INDEX_PATHS_IDS, logId, getVersion()), + getStorageFile(PATHS, logId, getVersion())); } @Override public void flush() throws StorageException { super.flush(); - myEmptyCommits.flush(); myPathsIndexer.getPathsEnumerator().force(); } @@ -148,12 +125,6 @@ public class VcsLogPathsIndex extends VcsLogFullDetailsIndex { @Override public void dispose() { super.dispose(); - try { - myEmptyCommits.close(); - } - catch (IOException e) { - LOG.warn(e); - } try { myPathsIndexer.getPathsEnumerator().close(); } @@ -162,26 +133,6 @@ public class VcsLogPathsIndex extends VcsLogFullDetailsIndex { } } - @Override - public void markCorrupted() { - super.markCorrupted(); - myEmptyCommits.markCorrupted(); - } - - @NotNull - public String getPathInfo(int commit) throws IOException { - if (myEmptyCommits.contains(commit)) { - return "No paths"; - } - Collection keys = getKeysForCommit(commit); - assert keys != null; - StringBuilder builder = new StringBuilder(); - for (int key : keys) { - builder.append(myPathsIndexer.getPathsEnumerator().valueOf(key)).append("\n"); - } - return builder.toString(); - } - private static class PathsIndexer implements DataIndexer { @NotNull private final PersistentEnumeratorBase myPathsEnumerator; @NotNull private final Set myRoots; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java index 3ca28ee70b36..0f1facb7c9a0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java @@ -23,25 +23,24 @@ import com.intellij.openapi.progress.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.EmptyConsumer; import com.intellij.util.Processor; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.EmptyIntHashSet; import com.intellij.util.indexing.StorageException; import com.intellij.util.indexing.ValueContainer; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.intellij.util.io.PersistentHashMap; -import com.intellij.util.io.PersistentMap; +import com.intellij.util.io.*; import com.intellij.vcs.log.*; import com.intellij.vcs.log.data.*; import com.intellij.vcs.log.impl.FatalErrorHandler; -import com.intellij.vcs.log.impl.VcsLogUtil; import com.intellij.vcs.log.impl.VcsLogUserFilterImpl; +import com.intellij.vcs.log.impl.VcsLogUtil; +import com.intellij.vcs.log.util.PersistentSet; import com.intellij.vcs.log.util.PersistentUtil; import com.intellij.vcs.log.util.StopWatch; import com.intellij.vcs.log.util.TroveUtil; @@ -68,10 +67,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull private final VcsUserRegistryImpl myUserRegistry; @NotNull private final Set myRoots; - @NotNull private final PersistentMap myMessagesIndex; - @Nullable private final VcsLogMessagesTrigramIndex myTrigramIndex; - @Nullable private final VcsLogUserIndex myUserIndex; - @Nullable private final VcsLogPathsIndex myPathsIndex; + @Nullable private final MyIndexStorage myIndexStorage; @NotNull private final SingleTaskController mySingleTaskController = new MySingleTaskController(); @NotNull private final Map myNumberOfTasks = ContainerUtil.newHashMap(); @@ -99,12 +95,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(myProject, VcsUserRegistry.class); - String logId = PersistentUtil.calcLogId(myProject, providers); - - myMessagesIndex = createMap(EnumeratorStringDescriptor.INSTANCE, "messages", logId, 0); - myTrigramIndex = createIndex(() -> new VcsLogMessagesTrigramIndex(logId, fatalErrorsConsumer, this)); - myUserIndex = createIndex(() -> new VcsLogUserIndex(logId, myUserRegistry, fatalErrorsConsumer, this)); - myPathsIndex = createIndex(() -> new VcsLogPathsIndex(logId, myRoots, fatalErrorsConsumer, this)); + myIndexStorage = createIndexStorage(fatalErrorsConsumer, PersistentUtil.calcLogId(myProject, providers)); for (VirtualFile root : myRoots) { myNumberOfTasks.put(root, new AtomicInteger()); @@ -113,14 +104,10 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { Disposer.register(disposableParent, this); } - public static int getVersion() { - return VcsLogStorageImpl.VERSION + VERSION; - } - - @Nullable - private I createIndex(@NotNull ThrowableComputable computable) { + protected MyIndexStorage createIndexStorage(@NotNull FatalErrorHandler fatalErrorHandler, @NotNull String logId) { try { - return computable.compute(); + return IOUtil.openCleanOrResetBroken(() -> new MyIndexStorage(logId, myUserRegistry, myRoots, fatalErrorHandler, this), + () -> MyIndexStorage.cleanup(logId)); } catch (IOException e) { myFatalErrorsConsumer.consume(this, e); @@ -128,17 +115,8 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { return null; } - @NotNull - private PersistentMap createMap(@NotNull KeyDescriptor descriptor, - @NotNull String kind, - @NotNull String logId, int version) { - try { - return PersistentUtil.createPersistentHashMap(descriptor, kind, logId, version); - } - catch (IOException e) { - myFatalErrorsConsumer.consume(this, e); - return new InMemoryMap<>(); - } + public static int getVersion() { + return VcsLogStorageImpl.VERSION + VERSION; } @Override @@ -155,14 +133,17 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { } private void storeDetails(@NotNull List details, boolean flush) { + if (myIndexStorage == null) return; try { for (VcsFullCommitDetails detail : details) { int index = myHashMap.getCommitIndex(detail.getId(), detail.getRoot()); - myMessagesIndex.put(index, detail.getFullMessage()); - if (myTrigramIndex != null) myTrigramIndex.update(index, detail); - if (myUserIndex != null) myUserIndex.update(index, detail); - if (myPathsIndex != null) myPathsIndex.update(index, detail); + myIndexStorage.messages.put(index, detail.getFullMessage()); + myIndexStorage.trigrams.update(index, detail); + myIndexStorage.users.update(index, detail); + myIndexStorage.paths.update(index, detail); + + myIndexStorage.commits.put(index); } if (flush) { flush(); @@ -175,10 +156,13 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { private void flush() { try { - myMessagesIndex.force(); - if (myTrigramIndex != null) myTrigramIndex.flush(); - if (myUserIndex != null) myUserIndex.flush(); - if (myPathsIndex != null) myPathsIndex.flush(); + if (myIndexStorage != null) { + myIndexStorage.messages.force(); + myIndexStorage.trigrams.flush(); + myIndexStorage.users.flush(); + myIndexStorage.paths.flush(); + myIndexStorage.commits.flush(); + } } catch (StorageException e) { myFatalErrorsConsumer.consume(this, e); @@ -186,19 +170,13 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { } public void markCorrupted() { - if (myMessagesIndex instanceof PersistentHashMap) ((PersistentHashMap)myMessagesIndex).markCorrupted(); - if (myTrigramIndex != null) myTrigramIndex.markCorrupted(); - if (myUserIndex != null) myUserIndex.markCorrupted(); - if (myPathsIndex != null) myPathsIndex.markCorrupted(); + if (myIndexStorage != null) myIndexStorage.commits.markCorrupted(); } @Override public boolean isIndexed(int commit) { try { - return myMessagesIndex.get(commit) != null && - (myUserIndex == null || myUserIndex.isIndexed(commit)) && - (myPathsIndex == null || myPathsIndex.isIndexed(commit)) && - (myTrigramIndex == null || myTrigramIndex.isIndexed(commit)); + return myIndexStorage == null || myIndexStorage.commits.contains(commit); } catch (IOException e) { myFatalErrorsConsumer.consume(this, e); @@ -225,6 +203,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull private TIntHashSet filter(@NotNull PersistentMap map, @NotNull Condition condition) { TIntHashSet result = new TIntHashSet(); + if (myIndexStorage == null) return result; try { Processor processor = integer -> { try { @@ -241,11 +220,11 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { } return true; }; - if (myMessagesIndex instanceof PersistentHashMap) { - ((PersistentHashMap)myMessagesIndex).processKeysWithExistingMapping(processor); + if (myIndexStorage.messages instanceof PersistentHashMap) { + ((PersistentHashMap)myIndexStorage.messages).processKeysWithExistingMapping(processor); } else { - myMessagesIndex.processKeys(processor); + myIndexStorage.messages.processKeys(processor); } } catch (IOException e) { @@ -257,9 +236,9 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull private TIntHashSet filterUsers(@NotNull Set users) { - if (myUserIndex != null) { + if (myIndexStorage != null) { try { - return myUserIndex.getCommitsForUsers(users); + return myIndexStorage.users.getCommitsForUsers(users); } catch (IOException | StorageException e) { myFatalErrorsConsumer.consume(this, e); @@ -270,9 +249,9 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull private TIntHashSet filterPaths(@NotNull Collection paths) { - if (myPathsIndex != null) { + if (myIndexStorage != null) { try { - return myPathsIndex.getCommitsForPaths(paths); + return myIndexStorage.paths.getCommitsForPaths(paths); } catch (IOException | StorageException e) { myFatalErrorsConsumer.consume(this, e); @@ -283,20 +262,20 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull public TIntHashSet filterMessages(@NotNull String text) { - if (myTrigramIndex != null) { + if (myIndexStorage != null) { try { if (VcsLogUtil.isRegexp(text)) { Pattern pattern = Pattern.compile(text); - return filter(myMessagesIndex, message -> pattern.matcher(message).find()); + return filter(myIndexStorage.messages, message -> pattern.matcher(message).find()); } else { - ValueContainer.IntIterator commitsForSearch = myTrigramIndex.getCommitsForSubstring(text); + ValueContainer.IntIterator commitsForSearch = myIndexStorage.trigrams.getCommitsForSubstring(text); if (commitsForSearch != null) { TIntHashSet result = new TIntHashSet(); while (commitsForSearch.hasNext()) { int commit = commitsForSearch.next(); try { - String value = myMessagesIndex.get(commit); + String value = myIndexStorage.messages.get(commit); if (value != null) { if (StringUtil.containsIgnoreCase(value, text)) { result.add(commit); @@ -315,18 +294,20 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { catch (StorageException e) { myFatalErrorsConsumer.consume(this, e); } + + return filter(myIndexStorage.messages, message -> StringUtil.containsIgnoreCase(message, text)); } - return filter(myMessagesIndex, message -> StringUtil.containsIgnoreCase(message, text)); + return EmptyIntHashSet.INSTANCE; } @Override public boolean canFilter(@NotNull List filters) { - if (filters.isEmpty()) return false; + if (filters.isEmpty() || myIndexStorage == null) return false; for (VcsLogDetailsFilter filter : filters) { - if (filter instanceof VcsLogTextFilter && myTrigramIndex != null || - filter instanceof VcsLogUserFilterImpl && myUserIndex != null || - filter instanceof VcsLogStructureFilter && myPathsIndex != null) { + if (filter instanceof VcsLogTextFilter || + filter instanceof VcsLogUserFilterImpl || + filter instanceof VcsLogStructureFilter) { continue; } return false; @@ -366,49 +347,61 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @Override public void dispose() { - try { - myMessagesIndex.close(); - } - catch (IOException e) { - LOG.warn(e); - } } - public void printDebugInfoForCommit(@NotNull CommitId commitId) { - int commit = myHashMap.getCommitIndex(commitId.getHash(), commitId.getRoot()); - if (!isIndexed(commit)) { - LOG.info("Commit " + commitId.getHash().asString() + " is not indexed."); - } - else { - StringBuilder builder = new StringBuilder(); - try { - builder.append("Commit ").append(commitId.getHash().asString()).append(" index info:\n"); + private static class MyIndexStorage { + private static final String COMMITS = "commits"; + private static final String MESSAGES = "messages"; + private static final int MESSAGES_VERSION = 0; + @NotNull private final PersistentSet commits; + @NotNull private final PersistentMap messages; + @NotNull private final VcsLogMessagesTrigramIndex trigrams; + @NotNull private final VcsLogUserIndex users; + @NotNull private final VcsLogPathsIndex paths; - builder.append("Message:\n").append(myMessagesIndex.get(commit)).append("\n"); - if (myTrigramIndex != null) { - builder.append("Trigrams:\n").append(myTrigramIndex.getTrigramInfo(commit)).append("\n"); - } - else { - builder.append("Trigrams index is null"); - } - if (myUserIndex != null) { - builder.append("User:\n").append(myUserIndex.getUserInfo(commit)).append("\n"); - } - else { - builder.append("User index is null"); - } - if (myPathsIndex != null) { - builder.append("Paths:\n").append(myPathsIndex.getPathInfo(commit)).append("\n"); - } - else { - builder.append("Paths index is null"); - } + public MyIndexStorage(@NotNull String logId, + @NotNull VcsUserRegistryImpl userRegistry, + @NotNull Set roots, + @NotNull FatalErrorHandler fatalErrorHandler, + @NotNull Disposable parentDisposable) + throws IOException { + Disposable disposable = Disposer.newDisposable(); + Disposer.register(parentDisposable, disposable); + + try { + commits = + PersistentUtil.createPersistentSetOrFailIfBroken(EnumeratorIntegerDescriptor.INSTANCE, COMMITS, logId, getVersion()); + Disposer.register(disposable, () -> catchAndWarn(commits::close)); + messages = new PersistentHashMap<>(PersistentUtil.getStorageFile(MESSAGES, logId, MESSAGES_VERSION), new IntInlineKeyDescriptor(), + EnumeratorStringDescriptor.INSTANCE, Page.PAGE_SIZE); + Disposer.register(disposable, () -> catchAndWarn(messages::close)); + + trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, disposable); + users = new VcsLogUserIndex(logId, userRegistry, fatalErrorHandler, disposable); + paths = new VcsLogPathsIndex(logId, roots, fatalErrorHandler, disposable); + } + catch (Throwable t) { + Disposer.dispose(disposable); + throw t; + } + } + + private static void catchAndWarn(@NotNull ThrowableRunnable runnable) { + try { + runnable.run(); } catch (IOException e) { - LOG.error(e); + LOG.warn(e); } + } - LOG.info(builder.toString()); + private static void cleanup(@NotNull String logId) { + IOUtil.deleteAllFilesStartingWith(PersistentUtil.getStorageFile(COMMITS, logId, getVersion())); + IOUtil.deleteAllFilesStartingWith(PersistentUtil.getStorageFile(MESSAGES, logId, MESSAGES_VERSION)); + + VcsLogMessagesTrigramIndex.getStorageFiles(logId).forEach(IOUtil::deleteAllFilesStartingWith); + VcsLogUserIndex.getStorageFiles(logId).forEach(IOUtil::deleteAllFilesStartingWith); + VcsLogPathsIndex.getStorageFiles(logId).forEach(IOUtil::deleteAllFilesStartingWith); } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogUserIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogUserIndex.java index 7a448b9c171c..4eca5916b5c5 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogUserIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogUserIndex.java @@ -31,26 +31,33 @@ import gnu.trove.THashMap; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; +import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Set; +import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion; + public class VcsLogUserIndex extends VcsLogFullDetailsIndex { private static final Logger LOG = Logger.getInstance(VcsLogUserIndex.class); + private static final String USERS = "users"; @NotNull private final VcsUserRegistryImpl myUserRegistry; public VcsLogUserIndex(@NotNull String logId, @NotNull VcsUserRegistryImpl userRegistry, @NotNull FatalErrorHandler consumer, @NotNull Disposable disposableParent) throws IOException { - super(logId, "users", VcsLogPersistentIndex.getVersion(), new UserIndexer(userRegistry), ScalarIndexExtension.VOID_DATA_EXTERNALIZER, + super(logId, USERS, getVersion(), new UserIndexer(userRegistry), ScalarIndexExtension.VOID_DATA_EXTERNALIZER, consumer, disposableParent); myUserRegistry = userRegistry; - ((UserIndexer)myIndexer).setFatalErrorConsumer(e -> { - consumer.consume(this, e); - markCorrupted(); - }); + ((UserIndexer)myIndexer).setFatalErrorConsumer(e -> consumer.consume(this, e)); + } + + @NotNull + public static Collection getStorageFiles(@NotNull String logId) { + return Collections.singletonList(getStorageFile(USERS, logId, getVersion())); } public TIntHashSet getCommitsForUsers(@NotNull Set users) throws IOException, StorageException { @@ -61,14 +68,6 @@ public class VcsLogUserIndex extends VcsLogFullDetailsIndex { return getCommitsWithAnyKey(ids); } - @NotNull - public String getUserInfo(int commit) throws IOException { - Collection keys = getKeysForCommit(commit); - assert keys != null; - assert keys.size() == 1; - return ObjectUtils.assertNotNull(myUserRegistry.getUserById(ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(keys)))).toString(); - } - private static class UserIndexer implements DataIndexer { @NotNull private final VcsUserRegistryImpl myRegistry; @NotNull private Consumer myFatalErrorConsumer = LOG::error; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/PrintIndexInfoAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/PrintIndexInfoAction.java deleted file mode 100644 index 6af11fef8d8a..000000000000 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/PrintIndexInfoAction.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2000-2016 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.ui.actions; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.MessageType; -import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; -import com.intellij.vcs.log.CommitId; -import com.intellij.vcs.log.VcsLog; -import com.intellij.vcs.log.VcsLogDataKeys; -import com.intellij.vcs.log.data.VcsLogData; -import com.intellij.vcs.log.data.index.VcsLogIndex; -import com.intellij.vcs.log.data.index.VcsLogPersistentIndex; -import com.intellij.vcs.log.impl.VcsProjectLog; - -import java.util.List; - -public class PrintIndexInfoAction extends DumbAwareAction { - @Override - public void update(AnActionEvent e) { - Presentation presentation = e.getPresentation(); - if (!Registry.is("vcs.log.highlight.not.indexed")) { - presentation.setEnabledAndVisible(false); - } - else { - Project project = e.getProject(); - VcsLog log = e.getData(VcsLogDataKeys.VCS_LOG); - if (project == null || log == null) { - presentation.setEnabledAndVisible(false); - } - else { - VcsLogData dataManager = VcsProjectLog.getInstance(project).getDataManager(); - if (dataManager == null) { - presentation.setEnabledAndVisible(false); - } - else { - VcsLogIndex index = dataManager.getIndex(); - if (!(index instanceof VcsLogPersistentIndex)) { - presentation.setEnabledAndVisible(false); - } - else { - presentation.setEnabledAndVisible(!log.getSelectedCommits().isEmpty()); - } - } - } - } - } - - @Override - public void actionPerformed(AnActionEvent e) { - Project project = e.getProject(); - VcsLog log = e.getData(VcsLogDataKeys.VCS_LOG); - if (project == null || log == null) { - return; - } - VcsLogData dataManager = VcsProjectLog.getInstance(project).getDataManager(); - if (dataManager == null) return; - VcsLogIndex index = dataManager.getIndex(); - if (!(index instanceof VcsLogPersistentIndex)) return; - - List commits = log.getSelectedCommits(); - for (CommitId commit : commits) { - ((VcsLogPersistentIndex)index).printDebugInfoForCommit(commit); - } - VcsBalloonProblemNotifier.showOverChangesView(project, "Index information for " + - commits.size() + " " + - StringUtil.pluralize("commit", commits.size()) + - " was written into log file", MessageType.INFO); - } -} diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentUtil.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentUtil.java index eb179679319c..dd17ff4b268d 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentUtil.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentUtil.java @@ -75,27 +75,12 @@ public class PersistentUtil { } @NotNull - public static PersistentSet createPersistentSet(@NotNull KeyDescriptor keyDescriptor, - @NotNull String storageKind, - @NotNull String logId, - int version) throws IOException { + public static PersistentSet createPersistentSetOrFailIfBroken(@NotNull KeyDescriptor keyDescriptor, + @NotNull String storageKind, + @NotNull String logId, + int version) throws IOException { File storageFile = getStorageFile(storageKind, logId, version); - - return IOUtil.openCleanOrResetBroken(() -> - new PersistentSetImpl<>(storageFile, keyDescriptor, Page.PAGE_SIZE, null, version), - storageFile); - } - - @NotNull - public static PersistentHashMap createPersistentHashMap(@NotNull DataExternalizer externalizer, - @NotNull String storageKind, - @NotNull String logId, - int version) throws IOException { - File storageFile = getStorageFile(storageKind, logId, version); - - return IOUtil.openCleanOrResetBroken(() -> - new PersistentHashMap<>(storageFile, new IntInlineKeyDescriptor(), externalizer, Page.PAGE_SIZE), - storageFile); + return new PersistentSetImpl<>(storageFile, keyDescriptor, Page.PAGE_SIZE, null, version); } @NotNull