@NotNull
  private FSRecords.NameId[] persistAllChildren(
      @NotNull final VirtualFile file, final int id, @NotNull FSRecords.NameId[] current) {
    assert file != mySuperRoot;
    final NewVirtualFileSystem fs = replaceWithNativeFS(getDelegate(file));

    String[] delegateNames = VfsUtil.filterNames(fs.list(file));
    if (delegateNames.length == 0 && current.length > 0) {
      return current;
    }

    Set<String> toAdd = ContainerUtil.newHashSet(delegateNames);
    for (FSRecords.NameId nameId : current) {
      toAdd.remove(nameId.name);
    }

    final TIntArrayList childrenIds = new TIntArrayList(current.length + toAdd.size());
    final List<FSRecords.NameId> nameIds =
        ContainerUtil.newArrayListWithExpectedSize(current.length + toAdd.size());
    for (FSRecords.NameId nameId : current) {
      childrenIds.add(nameId.id);
      nameIds.add(nameId);
    }
    for (String newName : toAdd) {
      FakeVirtualFile child = new FakeVirtualFile(file, newName);
      FileAttributes attributes = fs.getAttributes(child);
      if (attributes != null) {
        int childId = createAndFillRecord(fs, child, id, attributes);
        childrenIds.add(childId);
        nameIds.add(new FSRecords.NameId(childId, FileNameCache.storeName(newName), newName));
      }
    }

    FSRecords.updateList(id, childrenIds.toNativeArray());
    setChildrenCached(id);

    return nameIds.toArray(new FSRecords.NameId[nameIds.size()]);
  }
예제 #2
0
  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();
      }
    }
  }