[log] Use separate VcsLogHashMaps for different logs in a single project

Id is a sorted list of root & its vcs.
This commit is contained in:
Kirill Likhodedov
2014-10-15 16:54:02 +04:00
parent 73a800daa5
commit 81f1c4217b
2 changed files with 27 additions and 3 deletions
@@ -89,7 +89,7 @@ public class VcsLogDataHolder implements Disposable, VcsLogDataProvider {
myUserRegistry = (VcsUserRegistryImpl)ServiceManager.getService(project, VcsUserRegistry.class);
try {
myHashMap = new VcsLogHashMap(myProject);
myHashMap = new VcsLogHashMap(myProject, logProviders);
}
catch (IOException e) {
throw new RuntimeException(e); // TODO: show a message to the user & fallback to using in-memory Hashes
@@ -23,13 +23,18 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.IOUtil;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.io.Page;
import com.intellij.util.io.PersistentEnumerator;
import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsLogProvider;
import com.intellij.vcs.log.impl.HashImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,6 +43,9 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/**
* Supports the int <-> Hash persistent mapping.
@@ -49,8 +57,8 @@ public class VcsLogHashMap implements Disposable {
private final PersistentEnumerator<Hash> myPersistentEnumerator;
VcsLogHashMap(@NotNull Project project) throws IOException {
final File myMapFile = new File(LOG_CACHE_APP_DIR, project.getName() + "." + project.getLocationHash());
VcsLogHashMap(@NotNull Project project, @NotNull Map<VirtualFile, VcsLogProvider> logProviders) throws IOException {
final File myMapFile = new File(LOG_CACHE_APP_DIR, calcLogId(project, logProviders));
Disposer.register(project, this);
myPersistentEnumerator = IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentEnumerator<Hash>, IOException>() {
@Override
@@ -60,6 +68,22 @@ public class VcsLogHashMap implements Disposable {
}, myMapFile);
}
@NotNull
private static String calcLogId(@NotNull Project project, @NotNull final Map<VirtualFile, VcsLogProvider> logProviders) {
List<VirtualFile> sortedRoots = ContainerUtil.sorted(logProviders.keySet(), new Comparator<VirtualFile>() {
@Override
public int compare(VirtualFile o1, VirtualFile o2) {
return o1.getPath().compareTo(o2.getPath());
}
});
return project.getName() + "." + StringUtil.join(sortedRoots, new Function<VirtualFile, String>() {
@Override
public String fun(VirtualFile root) {
return root.getPath().hashCode() + "." + logProviders.get(root).getSupportedVcs().hashCode();
}
}, ".");
}
@Nullable
private Hash doGetHash(int index) throws IOException {
return myPersistentEnumerator.valueOf(index);