[vcs-log] keep indexes in one folder
authorJulia Beliaeva <Julia.Beliaeva@jetbrains.com>
Thu, 13 Oct 2016 19:28:22 +0000 (22:28 +0300)
committerJulia Beliaeva <Julia.Beliaeva@jetbrains.com>
Thu, 10 Nov 2016 17:12:25 +0000 (20:12 +0300)
Introduce new storage scheme: keep indexes in index/<project-log-id>.<index-id>.<version>

platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStorageImpl.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogFullDetailsIndex.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogMessagesTrigramIndex.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPathsIndex.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogUserIndex.java
platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentSetImpl.java [new file with mode: 0644]
platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentUtil.java

index 2bc928310cd044ea4901f686dacc304adb181a1e..cb6e2eb10e0028372a6e551b2d6f8eb237bb1299 100644 (file)
@@ -53,7 +53,6 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage {
   public static final int VERSION = 5;
   private static final int REFS_VERSION = 1;
   @NotNull private static final String ROOT_STORAGE_KIND = "roots";
-  private static final int ROOTS_STORAGE_VERSION = 0;
 
   public static final int NO_INDEX = -1;
 
@@ -79,7 +78,7 @@ public class VcsLogStorageImpl implements Disposable, VcsLogStorage {
 
     // cleanup old root storages, to remove after 2016.3 release
     PersistentUtil
-      .cleanupOldStorageFile(ROOT_STORAGE_KIND, project.getName() + "." + project.getBaseDir().getPath().hashCode(), ROOTS_STORAGE_VERSION);
+      .cleanupOldStorageFile(ROOT_STORAGE_KIND, project.getName() + "." + project.getBaseDir().getPath().hashCode());
 
     Disposer.register(parent, this);
   }
index 5b19a551225f7ae456e06f21453c8deb8a9836b5..389b2a0683306fddc0716268610b6395a1b9a073 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.vcs.log.data.index;
 import com.intellij.openapi.Disposable;
 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.DataExternalizer;
 import com.intellij.util.io.EnumeratorIntegerDescriptor;
@@ -37,8 +36,10 @@ import java.util.Collection;
 import java.util.Set;
 import java.util.function.ObjIntConsumer;
 
+import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion;
+
 public class VcsLogFullDetailsIndex<T> implements Disposable {
-  @NotNull protected static final String INDEX = "index-";
+  protected static final String INDEX = "index";
   @NotNull protected final MyMapReduceIndex myMapReduceIndex;
   @NotNull private final ID<Integer, T> myID;
   @NotNull private final String myLogId;
@@ -122,15 +123,8 @@ public class VcsLogFullDetailsIndex<T> implements Disposable {
   }
 
   @NotNull
-  public File getStorageFile(int version) {
-    return getStorageFile(INDEX + myName, myLogId, version);
-  }
-
-  @NotNull
-  public static File getStorageFile(@NotNull String kind, @NotNull String id, int version) {
-    File subdir = new File(PersistentUtil.LOG_CACHE, kind);
-    String safeLogId = PathUtilRt.suggestFileName(id, true, true);
-    return new File(subdir, safeLogId + "." + version);
+  public static File getStorageFile(@NotNull String kind, @NotNull String id) {
+    return PersistentUtil.getStorageFile(INDEX, kind, id, getVersion(), false);
   }
 
   private class MyMapReduceIndex extends MapReduceIndex<Integer, T, VcsFullCommitDetails> {
@@ -139,7 +133,7 @@ public class VcsLogFullDetailsIndex<T> implements Disposable {
                             @NotNull DataExternalizer<T> externalizer,
                             int version) throws IOException {
       super(new MyIndexExtension(indexer, externalizer, version),
-            new MapIndexStorage<>(getStorageFile(version),
+            new MapIndexStorage<>(getStorageFile(myName, myLogId),
                                   EnumeratorIntegerDescriptor.INSTANCE,
                                   externalizer, 5000));
     }
index 9872ab2e3153898ed3ac80a0ab5b26d6832b8914..c62dc82d592624100a8230d3f19219c77486ae75 100644 (file)
@@ -36,7 +36,7 @@ import java.util.Map;
 import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion;
 
 public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex<Void> {
-  private static final String TRIGRAMS = "trigrams";
+  public static final String TRIGRAMS = "trigrams";
 
   public VcsLogMessagesTrigramIndex(@NotNull String logId,
                                     @NotNull FatalErrorHandler fatalErrorHandler,
@@ -47,7 +47,7 @@ public class VcsLogMessagesTrigramIndex extends VcsLogFullDetailsIndex<Void> {
 
   @NotNull
   public static Collection<File> getStorageFiles(@NotNull String logId) {
-    return Collections.singletonList(getStorageFile(TRIGRAMS, logId, getVersion()));
+    return Collections.singletonList(getStorageFile(TRIGRAMS, logId));
   }
 
   @Nullable
index cd254b2b7c81213bc68b1c5f4e6d1ee84c6a1671..1c8d679595adf6bfe8bd64ac9c2cdcea59dbcd16 100644 (file)
@@ -52,8 +52,8 @@ import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion;
 
 public class VcsLogPathsIndex extends VcsLogFullDetailsIndex<Integer> {
   private static final Logger LOG = Logger.getInstance(VcsLogPathsIndex.class);
-  private static final String PATHS = "paths";
-  private static final String INDEX_PATHS_IDS = "index-paths-ids";
+  public static final String PATHS = "paths";
+  public static final String INDEX_PATHS_IDS = "paths-ids";
 
   @NotNull private final PathsIndexer myPathsIndexer;
 
@@ -70,8 +70,7 @@ public class VcsLogPathsIndex extends VcsLogFullDetailsIndex<Integer> {
 
   @NotNull
   private static PersistentEnumeratorBase<String> createPathsEnumerator(@NotNull String logId) throws IOException {
-    File storageFile = PersistentUtil.getStorageFile(INDEX_PATHS_IDS, logId, getVersion());
-
+    File storageFile = PersistentUtil.getStorageFile(INDEX, INDEX_PATHS_IDS, logId, getVersion(), true);
     return new PersistentBTreeEnumerator<>(storageFile, SystemInfo.isFileSystemCaseSensitive ? EnumeratorStringDescriptor.INSTANCE
                                                                                              : new ToLowerCaseStringDescriptor(),
                                            Page.PAGE_SIZE, null, getVersion());
@@ -79,8 +78,8 @@ public class VcsLogPathsIndex extends VcsLogFullDetailsIndex<Integer> {
 
   @NotNull
   public static Collection<File> getStorageFiles(@NotNull String logId) {
-    return Arrays.asList(PersistentUtil.getStorageFile(INDEX_PATHS_IDS, logId, getVersion()),
-                         getStorageFile(PATHS, logId, getVersion()));
+    return Arrays.asList(getStorageFile(INDEX_PATHS_IDS, logId),
+                         getStorageFile(PATHS, logId));
   }
 
   @Override
index efb8b63153f041b4f34b1a6c3b56fc01f9c90cad..c4dbc8351e65bd84b2c717b023d14090629799bb 100644 (file)
@@ -41,6 +41,7 @@ import com.intellij.vcs.log.impl.FatalErrorHandler;
 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.PersistentSetImpl;
 import com.intellij.vcs.log.util.PersistentUtil;
 import com.intellij.vcs.log.util.StopWatch;
 import com.intellij.vcs.log.util.TroveUtil;
@@ -48,12 +49,16 @@ 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.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
 import java.util.stream.IntStream;
 
+import static com.intellij.vcs.log.data.index.VcsLogFullDetailsIndex.INDEX;
+import static com.intellij.vcs.log.util.PersistentUtil.getStorageFile;
+
 public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
   private static final Logger LOG = Logger.getInstance(VcsLogPersistentIndex.class);
   private static final int BATCH_SIZE = 1000;
@@ -355,6 +360,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
     @NotNull private final VcsLogMessagesTrigramIndex trigrams;
     @NotNull private final VcsLogUserIndex users;
     @NotNull private final VcsLogPathsIndex paths;
+    private static final String INPUTS = "inputs";
 
     public MyIndexStorage(@NotNull String logId,
                           @NotNull VcsUserRegistryImpl userRegistry,
@@ -366,11 +372,15 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
       Disposer.register(parentDisposable, disposable);
 
       try {
-        commits =
-          PersistentUtil.createPersistentSetOrFailIfBroken(EnumeratorIntegerDescriptor.INSTANCE, COMMITS, logId, getVersion());
+        int version = getVersion();
+
+        File commitsStorage = getStorageFile(INDEX, COMMITS, logId, version, true);
+        commits = new PersistentSetImpl<>(commitsStorage, EnumeratorIntegerDescriptor.INSTANCE, Page.PAGE_SIZE, null, version);
         Disposer.register(disposable, () -> catchAndWarn(commits::close));
-        messages = new PersistentHashMap<>(PersistentUtil.getStorageFile(MESSAGES, logId, MESSAGES_VERSION), new IntInlineKeyDescriptor(),
-                                           EnumeratorStringDescriptor.INSTANCE, Page.PAGE_SIZE);
+
+        File messagesStorage = getStorageFile(INDEX, MESSAGES, logId, MESSAGES_VERSION, true);
+        messages = new PersistentHashMap<>(messagesStorage, new IntInlineKeyDescriptor(), EnumeratorStringDescriptor.INSTANCE,
+                                           Page.PAGE_SIZE);
         Disposer.register(disposable, () -> catchAndWarn(messages::close));
 
         trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, disposable);
@@ -381,6 +391,19 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
         Disposer.dispose(disposable);
         throw t;
       }
+
+      // cleanup of old index storage files
+      // to remove after 2017.1 release
+      PersistentUtil.cleanupOldStorageFile(MESSAGES, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + VcsLogMessagesTrigramIndex.TRIGRAMS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-no-" + VcsLogMessagesTrigramIndex.TRIGRAMS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + INPUTS + "-" + VcsLogMessagesTrigramIndex.TRIGRAMS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + VcsLogPathsIndex.PATHS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-no-" + VcsLogPathsIndex.PATHS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + VcsLogPathsIndex.PATHS + "-ids", logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + INPUTS + "-" + VcsLogPathsIndex.PATHS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + VcsLogUserIndex.USERS, logId);
+      PersistentUtil.cleanupOldStorageFile(INDEX + "-" + INPUTS + "-" + VcsLogUserIndex.USERS, logId);
     }
 
     private static void catchAndWarn(@NotNull ThrowableRunnable<IOException> runnable) {
@@ -393,8 +416,8 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable {
     }
 
     private static void cleanup(@NotNull String logId) {
-      IOUtil.deleteAllFilesStartingWith(PersistentUtil.getStorageFile(COMMITS, logId, getVersion()));
-      IOUtil.deleteAllFilesStartingWith(PersistentUtil.getStorageFile(MESSAGES, logId, MESSAGES_VERSION));
+      IOUtil.deleteAllFilesStartingWith(getStorageFile(COMMITS, logId, getVersion()));
+      IOUtil.deleteAllFilesStartingWith(getStorageFile(MESSAGES, logId, MESSAGES_VERSION));
 
       VcsLogMessagesTrigramIndex.getStorageFiles(logId).forEach(IOUtil::deleteAllFilesStartingWith);
       VcsLogUserIndex.getStorageFiles(logId).forEach(IOUtil::deleteAllFilesStartingWith);
index 4eca5916b5c5bd9ef2d4777342833302d61f10a5..49b78b16b48a8331594e051d91f45d6f16d87a02 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.vcs.log.data.index;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.util.Consumer;
-import com.intellij.util.ObjectUtils;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.indexing.DataIndexer;
 import com.intellij.util.indexing.ScalarIndexExtension;
@@ -42,7 +41,7 @@ import static com.intellij.vcs.log.data.index.VcsLogPersistentIndex.getVersion;
 
 public class VcsLogUserIndex extends VcsLogFullDetailsIndex<Void> {
   private static final Logger LOG = Logger.getInstance(VcsLogUserIndex.class);
-  private static final String USERS = "users";
+  public static final String USERS = "users";
   @NotNull private final VcsUserRegistryImpl myUserRegistry;
 
   public VcsLogUserIndex(@NotNull String logId,
@@ -57,7 +56,7 @@ public class VcsLogUserIndex extends VcsLogFullDetailsIndex<Void> {
 
   @NotNull
   public static Collection<File> getStorageFiles(@NotNull String logId) {
-    return Collections.singletonList(getStorageFile(USERS, logId, getVersion()));
+    return Collections.singletonList(getStorageFile(USERS, logId));
   }
 
   public TIntHashSet getCommitsForUsers(@NotNull Set<VcsUser> users) throws IOException, StorageException {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentSetImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/util/PersistentSetImpl.java
new file mode 100644 (file)
index 0000000..a1d9f70
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.io.PagedFileStorage;
+import com.intellij.util.io.PersistentBTreeEnumerator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+public 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();
+  }
+}
index dd17ff4b268d1300dcabe8a4d7e4eb010605efba..fe95a0c7e70074278c9a92b66455b0a45c66fcce 100644 (file)
@@ -24,7 +24,6 @@ import com.intellij.util.containers.ContainerUtil;
 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;
@@ -58,8 +57,15 @@ public class PersistentUtil {
     return mapFile;
   }
 
-  public static void cleanupOldStorageFile(@NotNull String storageKind, @NotNull String logId, int version) {
-    IOUtil.deleteAllFilesStartingWith(getStorageFile(storageKind, logId, version));
+  public static void cleanupOldStorageFile(@NotNull String storageKind, @NotNull String logId) {
+    File subdir = new File(LOG_CACHE, storageKind);
+    String safeLogId = PathUtilRt.suggestFileName(logId, true, true);
+    IOUtil.deleteAllFilesStartingWith(new File(subdir, safeLogId));
+
+    File[] files = subdir.listFiles();
+    if (files != null && files.length == 0) {
+      subdir.delete();
+    }
   }
 
   @NotNull
@@ -75,46 +81,22 @@ public class PersistentUtil {
   }
 
   @NotNull
-  public static <T> PersistentSet<T> createPersistentSetOrFailIfBroken(@NotNull KeyDescriptor<T> keyDescriptor,
-                                                                       @NotNull String storageKind,
-                                                                       @NotNull String logId,
-                                                                       int version) throws IOException {
-    File storageFile = getStorageFile(storageKind, logId, version);
-    return new PersistentSetImpl<>(storageFile, keyDescriptor, Page.PAGE_SIZE, null, version);
+  public static File getStorageFile(@NotNull String subdirName,
+                                    @NotNull String kind,
+                                    @NotNull String id,
+                                    int version,
+                                    boolean cleanup) {
+    File subdir = new File(LOG_CACHE, subdirName);
+    String safeLogId = PathUtilRt.suggestFileName(id, true, true);
+    File file = new File(subdir, safeLogId + "." + kind + "." + version);
+    if (cleanup && !file.exists()) {
+      IOUtil.deleteAllFilesStartingWith(new File(subdir, safeLogId + "." + kind));
+    }
+    return file;
   }
 
   @NotNull
   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();
-    }
-  }
 }