For keeping commits without changed paths or commits without trigrams set-like structure is sufficient. So PersistenceSet interface is created to represent such a structure with an implementation based on PersistentBTreeEnumerator. This allows to reduce the amount of occupied disk space.
import com.intellij.util.indexing.StorageException;
import com.intellij.util.indexing.ValueContainer;
import com.intellij.util.io.EnumeratorIntegerDescriptor;
-import com.intellij.util.io.PersistentHashMap;
import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.util.PersistentSet;
import com.intellij.vcs.log.util.PersistentUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex<Void> {
private static final Logger LOG = Logger.getInstance(VcsLogMessagesTrigramIndex.class);
private static final String TRIGRAMS = "trigrams";
- private static final int VALUE = 239;
- @NotNull private final PersistentHashMap<Integer, Integer> myNoTrigramsCommits;
+ @NotNull private final PersistentSet<Integer> myNoTrigramsCommits;
public VcsLogMessagesTrigramIndex(@NotNull String logId, @NotNull Disposable disposableParent) throws IOException {
super(logId, TRIGRAMS, VcsLogPersistentIndex.getVersion(), new TrigramMessageIndexer(), ScalarIndexExtension.VOID_DATA_EXTERNALIZER,
disposableParent);
myNoTrigramsCommits =
- PersistentUtil.createPersistentHashMap(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + TRIGRAMS, logId,
- VcsLogPersistentIndex.getVersion());
+ PersistentUtil.createPersistentSet(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + TRIGRAMS, logId,
+ VcsLogPersistentIndex.getVersion());
}
@Nullable
@Override
protected void onNotIndexableCommit(int commit) throws StorageException {
try {
- myNoTrigramsCommits.put(commit, VALUE);
+ myNoTrigramsCommits.put(commit);
}
catch (IOException e) {
throw new StorageException(e);
@Override
public boolean isIndexed(int commit) throws IOException {
- return super.isIndexed(commit) || myNoTrigramsCommits.containsMapping(commit);
+ return super.isIndexed(commit) || myNoTrigramsCommits.contains(commit);
}
@Override
public void flush() throws StorageException {
super.flush();
- myNoTrigramsCommits.force();
+ myNoTrigramsCommits.flush();
}
@Override
@NotNull
public String getTrigramInfo(int commit) throws IOException {
- if (myNoTrigramsCommits.containsMapping(commit)) {
+ if (myNoTrigramsCommits.contains(commit)) {
return "No trigrams";
}
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;
public class VcsLogPathsIndex extends VcsLogFullDetailsIndex<Integer> {
private static final Logger LOG = Logger.getInstance(VcsLogPathsIndex.class);
private static final String NAME = "paths";
- private static final int VALUE = 239;
- @NotNull private final PersistentHashMap<Integer, Integer> myEmptyCommits;
+ @NotNull private final PersistentSet<Integer> myEmptyCommits;
@NotNull private final PathsIndexer myPathsIndexer;
public VcsLogPathsIndex(@NotNull String logId,
super(logId, NAME, VcsLogPersistentIndex.getVersion(), new PathsIndexer(createPathsEnumerator(logId), roots),
new NullableIntKeyDescriptor(), disposableParent);
- myEmptyCommits = PersistentUtil.createPersistentHashMap(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + NAME, logId,
- VcsLogPersistentIndex.getVersion());
+ myEmptyCommits = PersistentUtil.createPersistentSet(EnumeratorIntegerDescriptor.INSTANCE, "index-no-" + NAME, logId,
+ VcsLogPersistentIndex.getVersion());
myPathsIndexer = (PathsIndexer)myIndexer;
myPathsIndexer.setFatalErrorConsumer(e -> {
fatalErrorHandler.consume(this, e);
@Override
protected void onNotIndexableCommit(int commit) throws StorageException {
try {
- myEmptyCommits.put(commit, VALUE);
+ myEmptyCommits.put(commit);
}
catch (IOException e) {
throw new StorageException(e);
@Override
public boolean isIndexed(int commit) throws IOException {
- return super.isIndexed(commit) || myEmptyCommits.containsMapping(commit);
+ return super.isIndexed(commit) || myEmptyCommits.contains(commit);
}
@Override
public void flush() throws StorageException {
super.flush();
- myEmptyCommits.force();
+ myEmptyCommits.flush();
myPathsIndexer.getPathsEnumerator().force();
}
@NotNull
public String getPathInfo(int commit) throws IOException {
- if (myEmptyCommits.containsMapping(commit)) {
+ if (myEmptyCommits.contains(commit)) {
return "No paths";
}
Collection<Integer> keys = getKeysForCommit(commit);
--- /dev/null
+/*
+ * 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.util;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+
+public interface PersistentSet<T> {
+
+ boolean contains(@NotNull T element) throws IOException;
+
+ void put(@NotNull T element) throws IOException;
+
+ void flush();
+
+ void markCorrupted();
+
+ void close() throws IOException;
+}
import com.intellij.util.io.*;
import com.intellij.vcs.log.VcsLogProvider;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
storageFile);
}
+ @NotNull
+ public static <T> PersistentSet<T> createPersistentSet(@NotNull KeyDescriptor<T> 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 <V> PersistentHashMap<Integer, V> createPersistentHashMap(@NotNull DataExternalizer<V> externalizer,
@NotNull String storageKind,
public static File getCorruptionMarkerFile() {
return new File(LOG_CACHE, CORRUPTION_MARKER);
}
+
+ public static class PersistentSetImpl<T> extends PersistentBTreeEnumerator<T> implements PersistentSet<T> {
+
+ public PersistentSetImpl(@NotNull File file,
+ @NotNull KeyDescriptor<T> dataDescriptor,
+ int initialSize,
+ @Nullable PagedFileStorage.StorageLockContext lockContext, int version) throws IOException {
+ super(file, dataDescriptor, initialSize, lockContext, version);
+ }
+
+ @Override
+ public boolean contains(@NotNull T element) throws IOException {
+ return tryEnumerate(element) != NULL_ID;
+ }
+
+ @Override
+ public void put(@NotNull T element) throws IOException {
+ enumerate(element);
+ }
+
+ @Override
+ public void flush() {
+ force();
+ }
+
+ @Override
+ public synchronized void markCorrupted() {
+ super.markCorrupted();
+ }
+ }
}