This commit is contained in:
Roman Shevchenko
2012-07-24 20:21:01 +02:00
parent 3768d8628e
commit 2de45c677f
5 changed files with 44 additions and 118 deletions
@@ -52,6 +52,9 @@ import java.util.Locale;
public abstract class LocalFileSystemBase extends LocalFileSystem {
protected static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl");
protected static final long DEFAULT_LENGTH = 0;
protected static final long DEFAULT_TIMESTAMP = 0;
private final List<LocalFileOperationsHandler> myHandlers = new ArrayList<LocalFileOperationsHandler>();
@Override
@@ -15,22 +15,25 @@
*/
package com.intellij.openapi.vfs.impl.win32;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.win32.FileInfo;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Map;
/**
* @author Dmitry Avdeev
*/
class Win32Kernel {
class Win32FsCache {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32FsCache");
private final IdeaWin32 myKernel = IdeaWin32.getInstance();
private final Map<String, FileInfo> myCache = new THashMap<String, FileInfo>();
@@ -39,11 +42,12 @@ class Win32Kernel {
}
@NotNull
public String[] list(@NotNull String absolutePath) {
String[] list(@NotNull String absolutePath) {
FileInfo[] fileInfos = myKernel.listChildren(absolutePath.replace('/', '\\') + "\\*.*");
if (fileInfos == null) {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
ArrayList<String> names = new ArrayList<String>(fileInfos.length);
for (FileInfo info : fileInfos) {
if (info.name.equals(".")) {
@@ -60,41 +64,14 @@ class Win32Kernel {
return ArrayUtil.toStringArray(names);
}
public void exists(@NotNull String path) throws FileNotFoundException {
getInfo(path);
}
public boolean isDirectory(@NotNull String path) throws FileNotFoundException {
FileInfo data = getInfo(path);
return (data.attributes & FileInfo.FILE_ATTRIBUTE_DIRECTORY) != 0;
}
public boolean isWritable(@NotNull String path) throws FileNotFoundException {
FileInfo fileInfo = getInfo(path);
myCache.remove(path);
return (fileInfo.attributes & FileInfo.FILE_ATTRIBUTE_READONLY) == 0;
}
public long getTimeStamp(@NotNull String path) throws FileNotFoundException {
long timestamp = getInfo(path).timestamp;
return timestamp / 10000 - 11644473600000l;
}
public long getLength(@NotNull String path) throws FileNotFoundException {
return getInfo(path).length;
}
@NotNull
private FileInfo getInfo(@NotNull String path) throws FileNotFoundException {
FileInfo info = doGetInfo(path);
if (info == null) {
throw new FileNotFoundException(path);
}
return info;
}
@Nullable
FileInfo doGetInfo(@NotNull String path) {
FileInfo getInfo(@NotNull VirtualFile file) {
// todo[r.sh]: uncomment and remove FS cache usage wherever it's not bulk?
//if (myCache.isEmpty()) {
// LOG.error("Called on empty cache - shouldn't happen");
//}
String path = file.getPath();
FileInfo info = myCache.get(path);
if (info == null) {
info = myKernel.getInfo(path.replace('/', '\\'));
@@ -107,8 +84,10 @@ class Win32Kernel {
}
@FileUtil.FileBooleanAttributes
public int getBooleanAttributes(@NotNull String path, @FileUtil.FileBooleanAttributes int flags) throws FileNotFoundException {
FileInfo info = getInfo(path);
int getBooleanAttributes(@NotNull VirtualFile file, @FileUtil.FileBooleanAttributes int flags) {
FileInfo info = getInfo(file);
if (info == null) return 0;
int result = 0;
if ((flags & FileUtil.BA_EXISTS) != 0) {
result |= FileUtil.BA_EXISTS;
@@ -15,7 +15,7 @@
*/
package com.intellij.openapi.vfs.impl.win32;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.win32.FileInfo;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.local.LocalFileSystemBase;
@@ -23,17 +23,16 @@ import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import static com.intellij.util.BitUtil.isSet;
import static com.intellij.util.BitUtil.notSet;
/**
* @author Dmitry Avdeev
*/
public class Win32LocalFileSystem extends LocalFileSystemBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem");
public static boolean isAvailable() {
return IdeaWin32.isAvailable();
}
@@ -46,14 +45,13 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
};
public static Win32LocalFileSystem getWin32Instance() {
if (!isAvailable()) throw new RuntimeException("DLL is not loaded");
if (!isAvailable()) throw new RuntimeException("Native filesystem for Windows is not loaded");
Win32LocalFileSystem fileSystem = THREAD_LOCAL.get();
fileSystem.myKernel.clearCache();
fileSystem.myFsCache.clearCache();
return fileSystem;
}
private final Win32Kernel myKernel = new Win32Kernel();
public static boolean checkMe = false;
private final Win32FsCache myFsCache = new Win32FsCache();
private Win32LocalFileSystem() { }
@@ -64,90 +62,37 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
try {
String[] strings = myKernel.list(file.getPath());
if (checkMe && !Arrays.asList(strings).equals(Arrays.asList(super.list(file)))) {
LOG.error(file.getPath());
}
return strings;
}
catch (Exception e) {
if (checkMe) {
assert false;
}
return super.list(file);
}
return myFsCache.list(file.getPath());
}
@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);
}
return myFsCache.getInfo(fileOrDirectory) != null;
}
@Override
public boolean isDirectory(@NotNull VirtualFile file) {
try {
boolean b = myKernel.isDirectory(file.getPath());
if (checkMe && b != super.isDirectory(file)) {
LOG.error(file.getPath());
}
return b;
}
catch (FileNotFoundException e) {
return super.isDirectory(file);
}
final FileInfo fileInfo = myFsCache.getInfo(file);
return fileInfo != null && isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_DIRECTORY);
}
@Override
public boolean isWritable(@NotNull VirtualFile file) {
try {
boolean b = myKernel.isWritable(file.getPath());
if (checkMe && b != super.isWritable(file)) {
LOG.error(file.getPath());
}
return b;
}
catch (FileNotFoundException e) {
return super.isWritable(file);
}
final FileInfo fileInfo = myFsCache.getInfo(file);
return fileInfo != null && notSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_READONLY);
}
@Override
public long getTimeStamp(@NotNull VirtualFile file) {
try {
long timeStamp = myKernel.getTimeStamp(file.getPath());
if (checkMe && timeStamp != super.getTimeStamp(file)) {
LOG.error(file.getPath());
}
return timeStamp;
}
catch (FileNotFoundException e) {
return super.getTimeStamp(file);
}
final FileInfo fileInfo = myFsCache.getInfo(file);
return fileInfo != null ? fileInfo.getTimestamp() : DEFAULT_TIMESTAMP;
}
@Override
public long getLength(@NotNull VirtualFile file) {
try {
long length = myKernel.getLength(file.getPath());
if (checkMe && length != super.getLength(file)) {
LOG.error(file.getPath());
}
return length;
}
catch (FileNotFoundException e) {
return super.getLength(file);
}
final FileInfo fileInfo = myFsCache.getInfo(file);
return fileInfo != null ? fileInfo.length : DEFAULT_LENGTH;
}
@NotNull
@@ -170,11 +115,6 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
@Override
public int getBooleanAttributes(@NotNull VirtualFile file, int flags) {
try {
return myKernel.getBooleanAttributes(file.getPath(), flags);
}
catch (FileNotFoundException e) {
return super.getBooleanAttributes(file, flags);
}
return myFsCache.getBooleanAttributes(file, flags);
}
}
@@ -367,7 +367,7 @@ public class FileSystemUtil {
final boolean isSymlink = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_REPARSE_POINT);
final boolean isHidden = isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_HIDDEN);
final boolean isWritable = !isSet(fileInfo.attributes, FileInfo.FILE_ATTRIBUTE_READONLY);
final long timestamp = fileInfo.timestamp / 10000 - 11644473600000l;
final long timestamp = fileInfo.getTimestamp();
return new FileAttributes(isDirectory, isSpecial, isSymlink, isHidden, fileInfo.length, timestamp, isWritable);
}
@@ -38,6 +38,10 @@ public class FileInfo {
public long timestamp;
public long length;
public long getTimestamp() {
return timestamp / 10000 - 11644473600000l;
}
public String toString() {
return name;
}