public void testFindRootWithDenormalizedPath() throws IOException {
    File tempJar = IoTestUtil.createTestJar();
    VirtualFile jar = refreshAndFindFile(tempJar);
    assertNotNull(jar);

    JarFileSystem fs = JarFileSystem.getInstance();
    NewVirtualFile root1 = ManagingFS.getInstance().findRoot(jar.getPath() + "!/", fs);
    NewVirtualFile root2 =
        ManagingFS.getInstance()
            .findRoot(jar.getParent().getPath() + "//" + jar.getName() + "!/", fs);
    assertNotNull(root1);
    assertSame(root1, root2);
  }
  public void testFindRootPerformance() throws IOException {
    File tempJar = IoTestUtil.createTestJar();
    final VirtualFile jar = refreshAndFindFile(tempJar);
    assertNotNull(jar);

    final JarFileSystem fs = JarFileSystem.getInstance();
    final NewVirtualFile root = ManagingFS.getInstance().findRoot(jar.getPath() + "!/", fs);
    PlatformTestUtil.startPerformanceTest(
            "find root is slow",
            500,
            new ThrowableRunnable() {
              @Override
              public void run() throws Throwable {
                final String path = jar.getPath() + "!/";
                JobLauncher.getInstance()
                    .invokeConcurrentlyUnderProgress(
                        Collections.nCopies(500, null),
                        null,
                        false,
                        new Processor<Object>() {
                          @Override
                          public boolean process(Object o) {
                            for (int i = 0; i < 1000; i++) {
                              NewVirtualFile rootJar = ManagingFS.getInstance().findRoot(path, fs);
                              assertNotNull(rootJar);
                              assertSame(root, rootJar);
                            }
                            return true;
                          }
                        });
              }
            })
        .assertTiming();
  }
Exemple #3
0
 @Nullable
 public VirtualFile getScratchVirtualFile() {
   final int id = SCRATCH_FILE_ID;
   if (id <= 0) {
     return null;
   }
   return ManagingFS.getInstance().findFileById(id);
 }
  public void testFindRootWithDenormalizedPath() {
    File tempDir =
        new WriteAction<File>() {
          @Override
          protected void run(Result<File> result) throws Throwable {
            File res = createTempDirectory();
            new File(res, "x.jar").createNewFile();
            result.setResult(res);
          }
        }.execute().getResultObject();
    VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir);
    VirtualFile jar = vDir.findChild("x.jar");
    assertNotNull(jar);

    NewVirtualFile root1 =
        ManagingFS.getInstance().findRoot(jar.getPath() + "!/", JarFileSystem.getInstance());
    NewVirtualFile root2 =
        ManagingFS.getInstance()
            .findRoot(
                jar.getParent().getPath() + "//" + jar.getName() + "!/",
                JarFileSystem.getInstance());
    assertNotNull(root1);
    assertSame(root1, root2);
  }
  public void testFindRootPerformance() {
    File tempDir =
        new WriteAction<File>() {
          @Override
          protected void run(Result<File> result) throws Throwable {
            File res = createTempDirectory();
            new File(res, "x.jar").createNewFile();
            result.setResult(res);
          }
        }.execute().getResultObject();
    final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDir);
    final VirtualFile jar = vDir.findChild("x.jar");
    assertNotNull(jar);

    final NewVirtualFile root =
        ManagingFS.getInstance().findRoot(jar.getPath() + "!/", JarFileSystem.getInstance());
    PlatformTestUtil.startPerformanceTest(
            "find root is slow",
            500,
            new ThrowableRunnable() {
              @Override
              public void run() throws Throwable {
                final String path = jar.getPath() + "!/";
                final JarFileSystem fileSystem = JarFileSystem.getInstance();
                JobLauncher.getInstance()
                    .invokeConcurrentlyUnderProgress(
                        Collections.nCopies(500, null),
                        null,
                        false,
                        new Processor<Object>() {
                          @Override
                          public boolean process(Object o) {
                            for (int i = 0; i < 1000; i++) {
                              NewVirtualFile rootJar =
                                  ManagingFS.getInstance().findRoot(path, fileSystem);
                              assertNotNull(rootJar);
                              assertSame(root, rootJar);
                            }
                            return true;
                          }
                        });
              }
            })
        .assertTiming();
  }
 private static void cleanPersistedVFSContent() {
   ((PersistentFS) ManagingFS.getInstance()).cleanPersistedContents();
 }
  @Override
  public <Key, Psi extends PsiElement> Collection<Psi> get(
      @NotNull final StubIndexKey<Key, Psi> indexKey,
      @NotNull final Key key,
      final Project project,
      final GlobalSearchScope scope) {
    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope);

    final PersistentFS fs = (PersistentFS) ManagingFS.getInstance();
    final PsiManager psiManager = PsiManager.getInstance(project);

    final List<Psi> result = new ArrayList<Psi>();
    final MyIndex<Key> index = (MyIndex<Key>) myIndices.get(indexKey);

    try {
      try {
        // disable up-to-date check to avoid locks on attempt to acquire index write lock while
        // holding at the same time the readLock for this index
        FileBasedIndex.disableUpToDateCheckForCurrentThread();
        index.getReadLock().lock();
        final ValueContainer<TIntArrayList> container = index.getData(key);

        container.forEach(
            new ValueContainer.ContainerAction<TIntArrayList>() {
              @Override
              public void perform(final int id, final TIntArrayList value) {
                final VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
                if (file != null && (scope == null || scope.contains(file))) {
                  StubTree stubTree = null;

                  final PsiFile _psifile = psiManager.findFile(file);
                  PsiFileWithStubSupport psiFile = null;

                  if (_psifile != null && !(_psifile instanceof PsiPlainTextFile)) {
                    if (_psifile instanceof PsiFileWithStubSupport) {
                      psiFile = (PsiFileWithStubSupport) _psifile;
                      stubTree = psiFile.getStubTree();
                      if (stubTree == null && psiFile instanceof PsiFileImpl) {
                        stubTree = ((PsiFileImpl) psiFile).calcStubTree();
                      }
                    }
                  }

                  if (stubTree != null || psiFile != null) {
                    if (stubTree == null) {
                      stubTree = StubTreeLoader.getInstance().readFromVFile(project, file);
                      if (stubTree != null) {
                        final List<StubElement<?>> plained = stubTree.getPlainList();
                        for (int i = 0; i < value.size(); i++) {
                          final StubElement<?> stub = plained.get(value.get(i));
                          final ASTNode tree = psiFile.findTreeForStub(stubTree, stub);

                          if (tree != null) {
                            if (tree.getElementType() == stubType(stub)) {
                              result.add((Psi) tree.getPsi());
                            } else {
                              String persistedStubTree =
                                  ((PsiFileStubImpl) stubTree.getRoot()).printTree();

                              String stubTreeJustBuilt =
                                  ((PsiFileStubImpl)
                                          ((IStubFileElementType)
                                                  ((PsiFileImpl) psiFile).getContentElementType())
                                              .getBuilder()
                                              .buildStubTree(psiFile))
                                      .printTree();

                              StringBuilder builder = new StringBuilder();
                              builder.append("Oops\n");

                              builder.append("Recorded stub:-----------------------------------\n");
                              builder.append(persistedStubTree);
                              builder.append(
                                  "\nAST built stub: ------------------------------------\n");
                              builder.append(stubTreeJustBuilt);
                              builder.append("\n");
                              LOG.info(builder.toString());

                              // requestReindex() may want to acquire write lock (for indices not
                              // requiring content loading)
                              // thus, because here we are under read lock, need to use invoke later
                              ApplicationManager.getApplication()
                                  .invokeLater(
                                      new Runnable() {
                                        @Override
                                        public void run() {
                                          FileBasedIndex.getInstance().requestReindex(file);
                                        }
                                      },
                                      ModalityState.NON_MODAL);
                            }
                          }
                        }
                      }
                    } else {
                      final List<StubElement<?>> plained = stubTree.getPlainList();
                      for (int i = 0; i < value.size(); i++) {
                        result.add((Psi) plained.get(value.get(i)).getPsi());
                      }
                    }
                  }
                }
              }
            });
      } finally {
        index.getReadLock().unlock();
        FileBasedIndex.enableUpToDateCheckForCurrentThread();
      }
    } catch (StorageException e) {
      forceRebuild(e);
    } catch (RuntimeException e) {
      final Throwable cause = FileBasedIndex.getCauseToRebuildIndex(e);
      if (cause != null) {
        forceRebuild(cause);
      } else {
        throw e;
      }
    }

    return result;
  }
  public void testChildrenAccessedButNotCached() throws Exception {
    File dir = createTempDirectory(false);
    ManagingFS managingFS = ManagingFS.getInstance();

    VirtualFile vFile =
        LocalFileSystem.getInstance()
            .refreshAndFindFileByPath(dir.getPath().replace(File.separatorChar, '/'));
    assertNotNull(vFile);
    assertFalse(managingFS.areChildrenLoaded(vFile));
    assertFalse(managingFS.wereChildrenAccessed(vFile));

    File child = new File(dir, "child");
    boolean created = child.createNewFile();
    assertTrue(created);

    File subdir = new File(dir, "subdir");
    boolean subdirCreated = subdir.mkdir();
    assertTrue(subdirCreated);

    File subChild = new File(subdir, "subdir");
    boolean subChildCreated = subChild.createNewFile();
    assertTrue(subChildCreated);

    VirtualFile childVFile =
        LocalFileSystem.getInstance()
            .refreshAndFindFileByPath(child.getPath().replace(File.separatorChar, '/'));
    assertNotNull(childVFile);
    assertFalse(managingFS.areChildrenLoaded(vFile));
    assertTrue(managingFS.wereChildrenAccessed(vFile));

    VirtualFile subdirVFile =
        LocalFileSystem.getInstance()
            .refreshAndFindFileByPath(subdir.getPath().replace(File.separatorChar, '/'));
    assertNotNull(subdirVFile);
    assertFalse(managingFS.areChildrenLoaded(subdirVFile));
    assertFalse(managingFS.wereChildrenAccessed(subdirVFile));
    assertFalse(managingFS.areChildrenLoaded(vFile));
    assertTrue(managingFS.wereChildrenAccessed(vFile));

    vFile.getChildren();
    assertTrue(managingFS.areChildrenLoaded(vFile));
    assertTrue(managingFS.wereChildrenAccessed(vFile));
    assertFalse(managingFS.areChildrenLoaded(subdirVFile));
    assertFalse(managingFS.wereChildrenAccessed(subdirVFile));

    VirtualFile subChildVFile =
        LocalFileSystem.getInstance()
            .refreshAndFindFileByPath(subChild.getPath().replace(File.separatorChar, '/'));
    assertNotNull(subChildVFile);
    assertTrue(managingFS.areChildrenLoaded(vFile));
    assertTrue(managingFS.wereChildrenAccessed(vFile));
    assertFalse(managingFS.areChildrenLoaded(subdirVFile));
    assertTrue(managingFS.wereChildrenAccessed(subdirVFile));
  }
  public void scan() {
    final NewVirtualFile root = (NewVirtualFile) myRefreshRoot;
    NewVirtualFileSystem delegate = root.getFileSystem();
    if (root.isDirty() && !delegate.exists(root)) {
      scheduleDeletion(root);
      root.markClean();
    } else {
      if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL)
          && root.isDirectory()
          && Registry.is("filesystem.useNative")) {

        if (SystemInfo.isWindows && Win32LocalFileSystem.isAvailable()) {
          delegate = Win32LocalFileSystem.getWin32Instance();
        }
      }

      final PersistentFS persistence = (PersistentFS) ManagingFS.getInstance();

      while (!myRefreshQueue.isEmpty()) {
        final VirtualFileSystemEntry file = (VirtualFileSystemEntry) myRefreshQueue.pullFirst();
        if (!file.isDirty()) continue;

        if (file.isDirectory()) {
          VirtualDirectoryImpl dir = (VirtualDirectoryImpl) file;
          final boolean fullSync = dir.allChildrenLoaded();
          if (fullSync) {
            Set<String> currentNames = new HashSet<String>(Arrays.asList(persistence.list(file)));
            Set<String> uptodateNames =
                new HashSet<String>(Arrays.asList(VfsUtil.filterNames(delegate.list(file))));

            Set<String> newNames = new HashSet<String>(uptodateNames);
            newNames.removeAll(currentNames);

            Set<String> deletedNames = new HashSet<String>(currentNames);
            deletedNames.removeAll(uptodateNames);

            for (String name : deletedNames) {
              scheduleDeletion(file.findChild(name));
            }

            for (String name : newNames) {
              boolean isDirectory = delegate.isDirectory(new FakeVirtualFile(file, name));
              scheduleCreation(file, name, isDirectory);
            }

            for (VirtualFile child : file.getChildren()) {
              if (!deletedNames.contains(child.getName())) {
                scheduleChildRefresh(file, child, delegate);
              }
            }
          } else {
            for (VirtualFile child : file.getCachedChildren()) {
              if (delegate.exists(child)) {
                scheduleChildRefresh(file, child, delegate);
              } else {
                scheduleDeletion(child);
              }
            }

            final List<String> names = dir.getSuspiciousNames();
            for (String name : names) {
              if (name.length() == 0) continue;

              final VirtualFile fake = new FakeVirtualFile(file, name);
              if (delegate.exists(fake)) {
                scheduleCreation(file, name, delegate.isDirectory(fake));
              }
            }
          }
        } else {
          long currentTimestamp = persistence.getTimeStamp(file);
          long updtodateTimestamp = delegate.getTimeStamp(file);

          if (currentTimestamp != updtodateTimestamp) {
            scheduleUpdateContent(file);
          }
        }

        boolean currentWritable = persistence.isWritable(file);
        boolean uptodateWritable = delegate.isWritable(file);

        if (currentWritable != uptodateWritable) {
          scheduleWritableAttributeChange(file, currentWritable, uptodateWritable);
        }

        file.markClean();
      }
    }
  }