mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimisation: way to get file boolean attributes in batch
This commit is contained in:
@@ -215,11 +215,12 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
for (VirtualFile vFile : myFile.getChildren()) {
|
||||
boolean isDir = vFile.isDirectory();
|
||||
if (processor instanceof PsiFileSystemItemProcessor &&
|
||||
!((PsiFileSystemItemProcessor)processor).acceptItem(vFile.getName(), vFile.isDirectory())) {
|
||||
!((PsiFileSystemItemProcessor)processor).acceptItem(vFile.getName(), isDir)) {
|
||||
continue;
|
||||
}
|
||||
if (vFile.isDirectory()) {
|
||||
if (isDir) {
|
||||
PsiDirectory dir = myManager.findDirectory(vFile);
|
||||
if (dir != null) {
|
||||
if (!processor.execute(dir)) return false;
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileListener;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -103,4 +104,48 @@ public abstract class NewVirtualFileSystem extends VirtualFileSystem implements
|
||||
public String getCanonicallyCasedName(@NotNull VirtualFile file) {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
public static final int BA_EXISTS = 0x01;
|
||||
public static final int BA_REGULAR = 0x02;
|
||||
public static final int BA_DIRECTORY = 0x04;
|
||||
public static final int BA_HIDDEN = 0x08;
|
||||
|
||||
@MagicConstant(flags = {BA_EXISTS, BA_REGULAR, BA_DIRECTORY, BA_HIDDEN})
|
||||
public @interface FileBooleanAttributes {}
|
||||
|
||||
/**
|
||||
* Queries the file about several attributes at once, and returns them ORed together.
|
||||
* This method is typically faster than several methods calls querying corresponding file attributes one by one.
|
||||
*
|
||||
* @param file to query.
|
||||
* @param flags Attributes to query the file for.
|
||||
* Each attribute is an int constant from this class.
|
||||
* Following attributes are defined:
|
||||
* <ul>
|
||||
* <li>{@link #BA_EXISTS} is set if {@link java.io.File#exists()} returns true</li>
|
||||
* <li>{@link #BA_DIRECTORY} is set if {@link java.io.File#isDirectory()} returns true</li>
|
||||
* <li>{@link #BA_HIDDEN} is set if {@link java.io.File#isHidden()} returns true</li>
|
||||
* <li>{@link #BA_REGULAR} is set if {@link java.io.File#isFile()} returns true</li>
|
||||
* </ul>
|
||||
* Attributes can be bitwise ORed together to query several file attributes at once.
|
||||
* <code>-1</code> as an argument value will query all attributes.
|
||||
* @return Attributes mask for the file, where the bit is set if the corresponding attribute for the file is true.
|
||||
* That is, the return value is <pre>{@code
|
||||
* (file.exists() ? BA_EXISTS : 0) |
|
||||
* (file.isDirectory()() ? BA_DIRECTORY : 0) |
|
||||
* (file.isRegular()() ? BA_REGULAR : 0) |
|
||||
* (file.isHidden()() ? BA_HIDDEN : 0)
|
||||
* }</pre>
|
||||
* Except that the bit in the return value is undefined if the corresponding bit in the flags parameter is not set.
|
||||
* <p>
|
||||
* Example usage:
|
||||
* <pre>{@code
|
||||
* int attributes = getBooleanAttributes(file, BA_EXISTS | BA_DIRECTORY);
|
||||
* if ((attributes & BA_EXISTS) != 0) {
|
||||
* // file exists
|
||||
* boolean isDirectory = (attributes & BA_DIRECTORY) != 0;
|
||||
* }}</pre>
|
||||
*/
|
||||
@FileBooleanAttributes
|
||||
public abstract int getBooleanAttributes(@NotNull final VirtualFile file, @FileBooleanAttributes int flags);
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ public class TempFileSystem extends NewVirtualFileSystem {
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class FSItem {
|
||||
private abstract static class FSItem {
|
||||
private final FSDir myParent;
|
||||
private String myName;
|
||||
private long myTimestamp;
|
||||
@@ -365,4 +365,13 @@ public class TempFileSystem extends NewVirtualFileSystem {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
FSItem item = convert(file);
|
||||
int isDir = item instanceof FSDir ? BA_DIRECTORY : 0;
|
||||
int exists = item == null ? 0 : BA_EXISTS;
|
||||
int regular = isDir == 0 ? BA_REGULAR : 0;
|
||||
return isDir | exists | regular;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,4 +365,22 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
|
||||
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
|
||||
return VfsImplUtil.refreshAndFindFileByPath(this, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
int exists = 0;
|
||||
JarHandler handler = getHandler(file);
|
||||
if ((flags & BA_EXISTS) != 0) {
|
||||
exists = handler.exists(file) ? BA_EXISTS : 0;
|
||||
}
|
||||
int isDir = 0;
|
||||
if ((flags & BA_DIRECTORY) != 0) {
|
||||
isDir = handler.isDirectory(file) ? BA_DIRECTORY : 0;
|
||||
}
|
||||
int regular = 0;
|
||||
if ((flags & BA_REGULAR) != 0) {
|
||||
regular = isDir == 0 ? BA_REGULAR : 0;
|
||||
}
|
||||
return exists | isDir | regular;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-8
@@ -25,10 +25,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
|
||||
import com.intellij.openapi.vfs.newvfs.ManagingFS;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
|
||||
import com.intellij.openapi.vfs.newvfs.VfsImplUtil;
|
||||
import com.intellij.openapi.vfs.newvfs.*;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -140,10 +137,6 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
|
||||
private static final Method JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD;
|
||||
private static final Object/* java.io.FileSystem */ JAVA_IO_FILESYSTEM;
|
||||
// copied from FileSystem
|
||||
private static final int BA_EXISTS = 0x01;
|
||||
private static final int BA_REGULAR = 0x02;
|
||||
private static final int BA_DIRECTORY = 0x04;
|
||||
private static final int BA_HIDDEN = 0x08;
|
||||
|
||||
static {
|
||||
Object fs;
|
||||
@@ -170,6 +163,8 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
|
||||
JAVA_IO_FILESYSTEM_GET_BOOLEAN_ATTRIBUTES_METHOD = getBooleanAttributes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
private static File convertToIOFileAndCheck(@NotNull final VirtualFile file) throws FileNotFoundException {
|
||||
final File ioFile = convertToIOFile(file);
|
||||
@@ -769,6 +764,17 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
int attributes = getBooleanAttributes(convertToIOFile(file));
|
||||
if (attributes != -1) return attributes & flags;
|
||||
return ((flags & BA_EXISTS) != 0 && exists(file) ? BA_EXISTS : 0) |
|
||||
((flags & BA_DIRECTORY) != 0 && isDirectory(file) ? BA_DIRECTORY : 0) |
|
||||
((flags & BA_REGULAR) != 0 && !isSpecialFile(file) ? BA_REGULAR : 0) |
|
||||
((flags & BA_HIDDEN) != 0 && convertToIOFile(file).isHidden() ? BA_HIDDEN : 0)
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(final boolean asynchronous) {
|
||||
RefreshQueue.getInstance().refresh(asynchronous, true, null, ManagingFS.getInstance().getRoots(this));
|
||||
|
||||
@@ -15,23 +15,28 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.impl.win32;
|
||||
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class FileInfo {
|
||||
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
public String name;
|
||||
public int attributes;
|
||||
public long timestamp;
|
||||
public long length;
|
||||
private static native void initIDs();
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
public String name;
|
||||
|
||||
@MagicConstant(flagsFromClass = Win32Kernel.class)
|
||||
public int attributes;
|
||||
|
||||
public long timestamp;
|
||||
public long length;
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.impl.win32;
|
||||
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
@@ -27,7 +30,10 @@ import java.util.Map;
|
||||
*/
|
||||
public class Win32Kernel {
|
||||
public static final int FILE_ATTRIBUTE_READONLY = 0x0001;
|
||||
public static final int FILE_ATTRIBUTE_HIDDEN = 0x0002;
|
||||
public static final int FILE_ATTRIBUTE_DIRECTORY = 0x0010;
|
||||
public static final int FILE_ATTRIBUTE_DEVICE = 0x0040;
|
||||
public static final int FILE_ATTRIBUTE_REPARSE_POINT = 0x0400;
|
||||
|
||||
private final IdeaWin32 myKernel = new IdeaWin32();
|
||||
|
||||
@@ -43,13 +49,12 @@ public class Win32Kernel {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
ArrayList<String> names = new ArrayList<String>(fileInfos.length);
|
||||
for (int i = 0, fileInfosLength = fileInfos.length; i < fileInfosLength; i++) {
|
||||
FileInfo info = fileInfos[i];
|
||||
for (FileInfo info : fileInfos) {
|
||||
if (info.name.equals(".")) {
|
||||
myCache.put(absolutePath, info);
|
||||
continue;
|
||||
}
|
||||
else if (info.name.equals("..")) {
|
||||
if (info.name.equals("..")) {
|
||||
continue;
|
||||
}
|
||||
myCache.put(absolutePath + "/" + info.name, info);
|
||||
@@ -59,8 +64,8 @@ public class Win32Kernel {
|
||||
return ArrayUtil.toStringArray(names);
|
||||
}
|
||||
|
||||
public void exists(String path) throws FileNotFoundException {
|
||||
getInfo(path);
|
||||
public boolean exists(String path) {
|
||||
return doGetInfo(path) != null;
|
||||
}
|
||||
|
||||
public boolean isDirectory(String path) throws FileNotFoundException {
|
||||
@@ -84,14 +89,42 @@ public class Win32Kernel {
|
||||
}
|
||||
|
||||
private FileInfo getInfo(String path) throws FileNotFoundException {
|
||||
FileInfo info = doGetInfo(path);
|
||||
if (info == null) {
|
||||
throw new FileNotFoundException(path);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileInfo doGetInfo(String path) {
|
||||
FileInfo info = myCache.get(path);
|
||||
if (info == null) {
|
||||
info = myKernel.getInfo(path.replace('/', '\\'));
|
||||
if (info == null) {
|
||||
throw new FileNotFoundException(path);
|
||||
return null;
|
||||
}
|
||||
myCache.put(path, info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@NewVirtualFileSystem.FileBooleanAttributes
|
||||
public int getBooleanAttributes(@NotNull String path, @NewVirtualFileSystem.FileBooleanAttributes int flags) {
|
||||
FileInfo info = doGetInfo(path);
|
||||
int result = 0;
|
||||
if ((flags & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
result |= info == null ? 0 : NewVirtualFileSystem.BA_EXISTS;
|
||||
}
|
||||
if ((flags & NewVirtualFileSystem.BA_DIRECTORY) != 0) {
|
||||
result |= info == null || (info.attributes & FILE_ATTRIBUTE_DIRECTORY) == 0 ? 0 : NewVirtualFileSystem.BA_DIRECTORY;
|
||||
}
|
||||
if ((flags & NewVirtualFileSystem.BA_REGULAR) != 0) {
|
||||
result |= info == null || (info.attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) != 0 ? 0 : NewVirtualFileSystem.BA_REGULAR;
|
||||
}
|
||||
if ((flags & NewVirtualFileSystem.BA_HIDDEN) != 0) {
|
||||
result |= info == null || (info.attributes & FILE_ATTRIBUTE_HIDDEN) == 0 ? 0 : NewVirtualFileSystem.BA_HIDDEN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-15
@@ -33,33 +33,34 @@ import java.util.Set;
|
||||
public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem");
|
||||
|
||||
private static boolean ourIsAvailable;
|
||||
private static final boolean ourIsAvailable;
|
||||
|
||||
static {
|
||||
boolean available = false;
|
||||
if (SystemInfo.isWindows) {
|
||||
String libName = SystemInfo.is64Bit ? "IdeaWin64" : "IdeaWin32";
|
||||
try {
|
||||
System.load(PathManager.getHomePath() + "/community/bin/win/" + libName + ".dll");
|
||||
ourIsAvailable = true;
|
||||
available = true;
|
||||
}
|
||||
catch (Throwable t0) {
|
||||
try {
|
||||
System.load(PathManager.getHomePath() + "/bin/win/" + libName + ".dll");
|
||||
ourIsAvailable = true;
|
||||
available = true;
|
||||
}
|
||||
catch (Throwable t1) {
|
||||
try {
|
||||
System.loadLibrary(libName);
|
||||
ourIsAvailable = true;
|
||||
available = true;
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
LOG.warn("Failed to load native filesystem for Windows", t2);
|
||||
ourIsAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ourIsAvailable) {
|
||||
ourIsAvailable = available;
|
||||
if (available) {
|
||||
LOG.info("Native filesystem for Windows is operational");
|
||||
}
|
||||
}
|
||||
@@ -108,16 +109,11 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
@Override
|
||||
public boolean exists(@NotNull VirtualFile fileOrDirectory) {
|
||||
if (fileOrDirectory.getParent() == null) return true;
|
||||
try {
|
||||
myKernel.exists(fileOrDirectory.getPath());
|
||||
if (checkMe && !super.exists(fileOrDirectory)) {
|
||||
LOG.error(fileOrDirectory.getPath());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
return super.exists(fileOrDirectory);
|
||||
boolean b = myKernel.exists(fileOrDirectory.getPath());
|
||||
if (checkMe && b != super.exists(fileOrDirectory)) {
|
||||
LOG.error(fileOrDirectory.getPath());
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,4 +192,9 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
public void removeWatchedRoot(@NotNull WatchRequest watchRequest) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
return myKernel.getBooleanAttributes(file.getPath(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
|
||||
@@ -312,14 +313,15 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
|
||||
return VfsUtil.toVirtualFileArray(roots);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private VirtualFileSystemEntry createAndFindChildWithEventFire(@NotNull String name) {
|
||||
final NewVirtualFileSystem delegate = getFileSystem();
|
||||
VirtualFile fake = new FakeVirtualFile(this, name);
|
||||
if (delegate.exists(fake)) {
|
||||
int attributes = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
|
||||
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
final String realName = delegate.getCanonicallyCasedName(fake);
|
||||
VFileCreateEvent event = new VFileCreateEvent(null, this, realName, delegate.isDirectory(fake), true);
|
||||
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
VFileCreateEvent event = new VFileCreateEvent(null, this, realName, isDir, true);
|
||||
RefreshQueue.getInstance().processSingleEvent(event);
|
||||
return findChild(realName);
|
||||
}
|
||||
@@ -526,14 +528,16 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
|
||||
final Map<String, VirtualFileSystemEntry> map = asMap();
|
||||
if (map == null) return Collections.emptyList();
|
||||
|
||||
List<String> names = new ArrayList<String>();
|
||||
List<String> names = null;
|
||||
|
||||
for (Map.Entry<String, VirtualFileSystemEntry> entry : map.entrySet()) {
|
||||
if (entry.getValue() == NULL_VIRTUAL_FILE) {
|
||||
if (names == null) names = new SmartList<String>();
|
||||
names.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
return names == null ? Collections.<String>emptyList() : names;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+37
-26
@@ -48,6 +48,7 @@ import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@@ -189,7 +190,8 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
childrenIds[i] = currentIds[idx];
|
||||
}
|
||||
else {
|
||||
int childId = createAndCopyRecord(delegate, new FakeVirtualFile(file, name), id);
|
||||
FakeVirtualFile child = new FakeVirtualFile(file, name);
|
||||
int childId = createAndCopyRecord(delegate, child, id, delegate.isDirectory(child));
|
||||
childrenIds[i] = childId;
|
||||
}
|
||||
}
|
||||
@@ -283,12 +285,16 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
return FSRecords.getModCount();
|
||||
}
|
||||
|
||||
private static boolean copyRecordFromDelegateFS(final int id, final int parentId, final VirtualFile file, NewVirtualFileSystem delegate) {
|
||||
private static boolean copyRecordFromDelegateFS(final int id,
|
||||
final int parentId,
|
||||
final VirtualFile file,
|
||||
NewVirtualFileSystem delegate,
|
||||
boolean isDir) {
|
||||
String name = file.getName();
|
||||
|
||||
if (name.length() > 0 && namesEqual(delegate, name, FSRecords.getName(id))) return false; // TODO: Handle root attributes change.
|
||||
if (!name.isEmpty() && namesEqual(delegate, name, FSRecords.getName(id))) return false; // TODO: Handle root attributes change.
|
||||
|
||||
if (name.length() == 0) { // TODO: hack
|
||||
if (name.isEmpty()) { // TODO: hack
|
||||
if (areChildrenLoaded(id)) return false;
|
||||
}
|
||||
|
||||
@@ -299,11 +305,9 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
|
||||
FSRecords.setTimestamp(id, delegate.getTimeStamp(file));
|
||||
|
||||
boolean directory = delegate.isDirectory(file);
|
||||
FSRecords.setLength(id, isDir ? -1L : delegate.getLength(file));
|
||||
|
||||
FSRecords.setLength(id, directory ? -1L : delegate.getLength(file));
|
||||
|
||||
FSRecords.setFlags(id, (directory ? IS_DIRECTORY_FLAG : 0) |
|
||||
FSRecords.setFlags(id, (isDir ? IS_DIRECTORY_FLAG : 0) |
|
||||
(delegate.isWritable(file) ? 0 : IS_READ_ONLY) |
|
||||
(delegate.isSymLink(file) ? IS_SYMLINK : 0) |
|
||||
(delegate.isSpecialFile(file) ? IS_SPECIAL : 0), true);
|
||||
@@ -398,8 +402,10 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
}
|
||||
|
||||
VirtualFile fake = new FakeVirtualFile(parent, childName);
|
||||
if (delegate.exists(fake)) {
|
||||
int child = createAndCopyRecord(delegate, fake, parentId);
|
||||
int attributes = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
|
||||
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
int child = createAndCopyRecord(delegate, fake, parentId, isDir);
|
||||
FSRecords.updateList(parentId, ArrayUtil.append(children, child));
|
||||
return child;
|
||||
}
|
||||
@@ -722,13 +728,13 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
synchronized (LOCK) {
|
||||
final String rootUrl = fs.getProtocol() + "://" + basePath;
|
||||
VirtualFileSystemEntry root = myRoots.get(rootUrl);
|
||||
if (root == null && basePath.length() == 0) {
|
||||
if (root == null && basePath.isEmpty()) {
|
||||
root = myFakeRoot;
|
||||
}
|
||||
if (root == null) {
|
||||
try {
|
||||
final int rootId = FSRecords.findRootRecord(rootUrl);
|
||||
if (basePath.length() > 0) {
|
||||
if (!basePath.isEmpty()) {
|
||||
root = new VirtualDirectoryImpl(basePath, null, fs, rootId) {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -756,14 +762,14 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
|
||||
@Override
|
||||
public VirtualFileSystemEntry findChild(@NotNull String name) {
|
||||
if (name.length() == 0) return null;
|
||||
if (name.isEmpty()) return null;
|
||||
return findRoot(name, fs);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (!fs.exists(root)) return null;
|
||||
|
||||
boolean newRoot = copyRecordFromDelegateFS(rootId, 0, root, fs);
|
||||
boolean newRoot = copyRecordFromDelegateFS(rootId, 0, root, fs, true);
|
||||
if (!newRoot) {
|
||||
if (fs.getTimeStamp(root) != FSRecords.getTimestamp(rootId)) {
|
||||
root.markDirtyRecursively();
|
||||
@@ -774,7 +780,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (basePath.length() > 0) {
|
||||
if (!basePath.isEmpty()) {
|
||||
myRoots.put(rootUrl, root);
|
||||
myRootsById.put(root.getId(), root);
|
||||
}
|
||||
@@ -949,10 +955,12 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
|
||||
private static void executeCreateChild(final VirtualFile parent, final String name) {
|
||||
final NewVirtualFileSystem delegate = getDelegate(parent);
|
||||
VirtualFile fakeFile = new FakeVirtualFile(parent, name);
|
||||
if (delegate.exists(fakeFile)) {
|
||||
VirtualFile fake = new FakeVirtualFile(parent, name);
|
||||
int attributes = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
|
||||
if ((attributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
final int parentId = getFileId(parent);
|
||||
int childId = createAndCopyRecord(delegate, fakeFile, parentId);
|
||||
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
int childId = createAndCopyRecord(delegate, fake, parentId, isDir);
|
||||
|
||||
appendIdToParentList(parentId, childId);
|
||||
final VirtualDirectoryImpl dir = (VirtualDirectoryImpl)parent;
|
||||
@@ -960,9 +968,9 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
}
|
||||
}
|
||||
|
||||
private static int createAndCopyRecord(NewVirtualFileSystem delegateSystem, VirtualFile delegateFile, int parentId) {
|
||||
private static int createAndCopyRecord(NewVirtualFileSystem delegateSystem, VirtualFile delegateFile, int parentId, boolean isDir) {
|
||||
int childId = FSRecords.createRecord();
|
||||
copyRecordFromDelegateFS(childId, parentId, delegateFile, delegateSystem);
|
||||
copyRecordFromDelegateFS(childId, parentId, delegateFile, delegateSystem, isDir);
|
||||
return childId;
|
||||
}
|
||||
|
||||
@@ -1067,7 +1075,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
FSRecords.setLength(getFileId(file), delegate.getLength(file));
|
||||
FSRecords.setTimestamp(getFileId(file), delegate.getTimeStamp(file));
|
||||
|
||||
((NewVirtualFile)file).setModificationStamp(newModificationStamp);
|
||||
((VirtualFileSystemEntry)file).setModificationStamp(newModificationStamp);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
@@ -1092,6 +1100,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
return FSRecords.getName(id);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void cleanPersistedContents() {
|
||||
try {
|
||||
final int[] roots = FSRecords.listRoots();
|
||||
@@ -1104,6 +1113,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
private static void cleanPersistedContentsRecursively(int id) {
|
||||
if (isDirectory(id)) {
|
||||
for (int child : FSRecords.list(id)) {
|
||||
@@ -1116,11 +1126,12 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
|
||||
}
|
||||
|
||||
public static NewVirtualFileSystem replaceWithNativeFS(NewVirtualFileSystem delegate) {
|
||||
if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL) && Registry.is("filesystem.useNative")) {
|
||||
if (SystemInfo.isWindows && Win32LocalFileSystem.isAvailable()) {
|
||||
delegate = Win32LocalFileSystem.getWin32Instance();
|
||||
}
|
||||
}
|
||||
if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL) &&
|
||||
Registry.is("filesystem.useNative") &&
|
||||
SystemInfo.isWindows &&
|
||||
Win32LocalFileSystem.isAvailable()) {
|
||||
delegate = Win32LocalFileSystem.getWin32Instance();
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-11
@@ -25,6 +25,7 @@ import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -47,12 +48,15 @@ public class RefreshWorker {
|
||||
public void scan() {
|
||||
final NewVirtualFile root = (NewVirtualFile)myRefreshRoot;
|
||||
NewVirtualFileSystem delegate = root.getFileSystem();
|
||||
if (root.isDirty() && !delegate.exists(root)) {
|
||||
int attributes = delegate.getBooleanAttributes(root, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
|
||||
|
||||
if (root.isDirty() && (attributes & NewVirtualFileSystem.BA_EXISTS) == 0) {
|
||||
scheduleDeletion(root);
|
||||
root.markClean();
|
||||
}
|
||||
else {
|
||||
if (root.isDirectory()) {
|
||||
boolean isDir = (attributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
if (isDir) {
|
||||
delegate = PersistentFS.replaceWithNativeFS(delegate);
|
||||
}
|
||||
|
||||
@@ -86,14 +90,16 @@ public class RefreshWorker {
|
||||
|
||||
for (VirtualFile child : file.getChildren()) {
|
||||
if (!deletedNames.contains(child.getName())) {
|
||||
scheduleChildRefresh(file, child, delegate);
|
||||
int childAttributes = delegate.getBooleanAttributes(child, -1);
|
||||
scheduleChildRefresh(file, child, delegate, childAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (VirtualFile child : file.getCachedChildren()) {
|
||||
if (delegate.exists(child)) {
|
||||
scheduleChildRefresh(file, child, delegate);
|
||||
int childAttributes = delegate.getBooleanAttributes(child, -1);
|
||||
if ((childAttributes & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
scheduleChildRefresh(file, child, delegate, childAttributes);
|
||||
}
|
||||
else {
|
||||
scheduleDeletion(child);
|
||||
@@ -102,11 +108,13 @@ public class RefreshWorker {
|
||||
|
||||
final List<String> names = dir.getSuspiciousNames();
|
||||
for (String name : names) {
|
||||
if (name.length() == 0) continue;
|
||||
if (name.isEmpty()) continue;
|
||||
|
||||
final VirtualFile fake = new FakeVirtualFile(file, name);
|
||||
if (delegate.exists(fake)) {
|
||||
scheduleCreation(file, name, delegate.isDirectory(fake));
|
||||
int attrs = delegate.getBooleanAttributes(fake, NewVirtualFileSystem.BA_EXISTS | NewVirtualFileSystem.BA_DIRECTORY);
|
||||
if ((attrs & NewVirtualFileSystem.BA_EXISTS) != 0) {
|
||||
boolean isDira = (attrs & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
scheduleCreation(file, name, isDira);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,13 +140,16 @@ public class RefreshWorker {
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleChildRefresh(final VirtualFileSystemEntry file, final VirtualFile child, final NewVirtualFileSystem delegate) {
|
||||
private void scheduleChildRefresh(@NotNull VirtualFileSystemEntry file,
|
||||
@NotNull VirtualFile child,
|
||||
@NotNull NewVirtualFileSystem delegate,
|
||||
@NewVirtualFileSystem.FileBooleanAttributes int childAttributes) {
|
||||
final boolean currentIsDirectory = child.isDirectory();
|
||||
final boolean currentIsSymlink = child.isSymLink();
|
||||
final boolean currentIsSpecial = child.isSpecialFile();
|
||||
final boolean upToDateIsDirectory = delegate.isDirectory(child);
|
||||
final boolean upToDateIsDirectory = (childAttributes & NewVirtualFileSystem.BA_DIRECTORY) != 0;
|
||||
final boolean upToDateIsSymlink = delegate.isSymLink(child);
|
||||
final boolean upToDateIsSpecial = delegate.isSpecialFile(child);
|
||||
final boolean upToDateIsSpecial = (childAttributes & (NewVirtualFileSystem.BA_REGULAR | NewVirtualFileSystem.BA_DIRECTORY | NewVirtualFileSystem.BA_EXISTS)) == NewVirtualFileSystem.BA_EXISTS;
|
||||
if (currentIsDirectory != upToDateIsDirectory || currentIsSymlink != upToDateIsSymlink || currentIsSpecial != upToDateIsSpecial) {
|
||||
scheduleDeletion(child);
|
||||
scheduleReCreation(file, child.getName(), upToDateIsDirectory);
|
||||
|
||||
@@ -251,4 +251,9 @@ public class MockLocalFileSystem extends LocalFileSystem {
|
||||
public int getRank() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
|
||||
public class FileUtil {
|
||||
public static final int MEGABYTE = 1024 * 1024;
|
||||
public static final String ASYNC_DELETE_EXTENSION = ".__del__";
|
||||
@NonNls public static final String ASYNC_DELETE_EXTENSION = ".__del__";
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.FileUtil");
|
||||
|
||||
@@ -681,7 +681,7 @@ public class FileUtil {
|
||||
final int oldPermissions = FileSystemUtil.getPermissions(fromFile);
|
||||
final int newPermissions = FileSystemUtil.getPermissions(toFile);
|
||||
if (oldPermissions != -1 && newPermissions != -1) {
|
||||
FileSystemUtil.setPermissions(toFile, (oldPermissions | newPermissions));
|
||||
FileSystemUtil.setPermissions(toFile, oldPermissions | newPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -713,7 +713,7 @@ public class FileUtil {
|
||||
public static void copyDir(@NotNull File fromDir, @NotNull File toDir, boolean copySystemFiles) throws IOException {
|
||||
copyDir(fromDir, toDir, copySystemFiles ? null : new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return !file.getName().startsWith(".");
|
||||
return !StringUtil.startsWithChar(file.getName(), '.');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -939,7 +939,7 @@ public class FileUtil {
|
||||
final StringBuilder builder = new StringBuilder(antPattern.length());
|
||||
int asteriskCount = 0;
|
||||
boolean recursive = true;
|
||||
final int start = ignoreStartingSlash && (antPattern.startsWith("/") || antPattern.startsWith("\\")) ? 1 : 0;
|
||||
final int start = ignoreStartingSlash && (StringUtil.startsWithChar(antPattern, '/') || StringUtil.startsWithChar(antPattern, '\\')) ? 1 : 0;
|
||||
for (int idx = start; idx < antPattern.length(); idx++) {
|
||||
final char ch = antPattern.charAt(idx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user