From b830ec36b5f8919ef242282bd655c1c0a8f8efce Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 13 Mar 2017 18:33:39 +0100 Subject: [PATCH] store index's version stamp inside index file, instead of file's lastModified --- .../intellij/psi/stubs/StubUpdatingIndex.java | 2 +- .../intellij/psi/stubs/StubVersionMap.java | 70 ++++++++++--------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 5bd932639e1d..34725c6d93d0 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -50,7 +50,7 @@ import java.util.*; public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtension implements PsiDependentIndex, CustomInputsIndexFileBasedIndexExtension { static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.StubUpdatingIndex"); - private static final int VERSION = 31 + (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 1 : 0); + private static final int VERSION = 32 + (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 1 : 0); // todo remove once we don't need this for stub-ast mismatch debug info private static final FileAttribute INDEXED_STAMP = new FileAttribute("stubIndexStamp", 2, true); diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubVersionMap.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubVersionMap.java index e44de4c881ef..72163f2880a1 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubVersionMap.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubVersionMap.java @@ -73,47 +73,53 @@ class StubVersionMap { List addedFileTypes = new ArrayList<>(); long lastUsedCounter = currentStubIndexStamp; - if (allIndexedFiles.lastModified() == currentStubIndexStamp) { - FileTypeRegistry fileTypeRegistry = FileTypeRegistry.getInstance(); + boolean canUsePreviousMappings = allIndexedFiles.exists(); + FileTypeRegistry fileTypeRegistry = FileTypeRegistry.getInstance(); + Set loadedFileTypes = new THashSet<>(); - Set loadedFileTypes = new THashSet<>(); + if (canUsePreviousMappings) { + List stringList = StringUtil.split(FileUtil.loadFile(allIndexedFiles, ourEncoding), LINE_SEPARATOR); + long allIndexedFilesVersion = Long.parseLong(stringList.get(0)); + + if (allIndexedFilesVersion == currentStubIndexStamp) { + for (int i = 1, size = stringList.size(); i < size; ++i) { + List strings = StringUtil.split(stringList.get(i), RECORD_SEPARATOR); + String fileTypeName = strings.get(0); + long usedTimeStamp = Long.parseLong(strings.get(2)); + lastUsedCounter = Math.min(lastUsedCounter, usedTimeStamp); - for(String fileTypeInfo: StringUtil.split(FileUtil.loadFile(allIndexedFiles, ourEncoding), LINE_SEPARATOR)) { - List strings = StringUtil.split(fileTypeInfo, RECORD_SEPARATOR); - String fileTypeName = strings.get(0); - long usedTimeStamp = Long.parseLong(strings.get(2)); - lastUsedCounter = Math.min(lastUsedCounter, usedTimeStamp); - - FileType fileType = fileTypeRegistry.findFileTypeByName(fileTypeName); - if (fileType == null) removedFileTypes.add(fileTypeName); - else { - loadedFileTypes.add(fileType); - Object owner = getVersionOwner(fileType); - if (owner == null) removedFileTypes.add(fileTypeName); + FileType fileType = fileTypeRegistry.findFileTypeByName(fileTypeName); + if (fileType == null) removedFileTypes.add(fileTypeName); else { - if (!Comparing.equal(strings.get(1), typeAndVersion(owner))) { - updatedFileTypes.add(fileType); - } else { - registerStamp(fileType, usedTimeStamp); + loadedFileTypes.add(fileType); + Object owner = getVersionOwner(fileType); + if (owner == null) removedFileTypes.add(fileTypeName); + else { + if (!Comparing.equal(strings.get(1), typeAndVersion(owner))) { + updatedFileTypes.add(fileType); + } + else { + registerStamp(fileType, usedTimeStamp); + } } } } + } else { + canUsePreviousMappings = false; } + } - for(FileType fileType:fileTypeToVersionOwner.keySet()) { - if (!loadedFileTypes.contains(fileType)) { - addedFileTypes.add(fileType); - } + for(FileType fileType:fileTypeToVersionOwner.keySet()) { + if (!loadedFileTypes.contains(fileType)) { + addedFileTypes.add(fileType); } + } - if (!addedFileTypes.isEmpty() || !removedFileTypes.isEmpty()) { - StubUpdatingIndex.LOG.info("requesting complete stub index rebuild due to changes: " + - (addedFileTypes.isEmpty() ? "" : "added file types:" + StringUtil.join(addedFileTypes, FileType::getName, ",") + ";") + - (removedFileTypes.isEmpty() ? "":"removed file types:" + StringUtil.join(removedFileTypes, ","))); - throw new IOException(); // StubVersionMap will be recreated - } - } else { - addedFileTypes.addAll(fileTypeToVersionOwner.keySet()); + if (canUsePreviousMappings && (!addedFileTypes.isEmpty() || !removedFileTypes.isEmpty())) { + StubUpdatingIndex.LOG.info("requesting complete stub index rebuild due to changes: " + + (addedFileTypes.isEmpty() ? "" : "added file types:" + StringUtil.join(addedFileTypes, FileType::getName, ",") + ";") + + (removedFileTypes.isEmpty() ? "":"removed file types:" + StringUtil.join(removedFileTypes, ","))); + throw new IOException(); // StubVersionMap will be recreated } long counter = lastUsedCounter - 1; // important to start with value smaller and progress downwards @@ -136,6 +142,7 @@ class StubVersionMap { } StringBuilder allFileTypes = new StringBuilder(); + allFileTypes.append(currentStubIndexStamp).append(LINE_SEPARATOR); for (FileType fileType : fileTypeToVersionOwner.keySet()) { Object owner = fileTypeToVersionOwner.get(fileType); @@ -144,7 +151,6 @@ class StubVersionMap { .append(timestamp).append(LINE_SEPARATOR); } FileUtil.writeToFile(allIndexedFiles, allFileTypes.toString().getBytes(ourEncoding)); - FileUtil.setLastModified(allIndexedFiles, currentStubIndexStamp); } myStubIndexStamp = currentStubIndexStamp;