diff --git a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java index 10bf9caa9200..c7fa8a49e814 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/vfs/VirtualFilePointerTest.java @@ -1,21 +1,27 @@ package com.intellij.openapi.vfs; +import com.intellij.concurrency.JobUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.impl.VirtualFilePointerImpl; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.Processor; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; /** * @author dsl @@ -23,7 +29,13 @@ import java.util.ArrayList; public class VirtualFilePointerTest extends IdeaTestCase { private VirtualFilePointerManager myVirtualFilePointerManager; - static class LoggingListener implements VirtualFilePointerListener { + @Override + protected void setUp() throws Exception { + super.setUp(); + myVirtualFilePointerManager = VirtualFilePointerManager.getInstance(); + } + + private static class LoggingListener implements VirtualFilePointerListener { private final ArrayList myLog = new ArrayList(); @Override @@ -100,7 +112,7 @@ public class VirtualFilePointerTest extends IdeaTestCase { }; ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override - public void run () { + public void run() { VirtualFileManager.getInstance().refresh(false); final VirtualFile virtualFile = getVirtualFile(tempDirectory); virtualFile.refresh(false, true); @@ -165,7 +177,7 @@ public class VirtualFilePointerTest extends IdeaTestCase { }; ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override - public void run () { + public void run() { VirtualFileManager.getInstance().refresh(false); final VirtualFile virtualFile = getVirtualFile(tempDirectory); virtualFile.refresh(false, true); @@ -392,9 +404,87 @@ public class VirtualFilePointerTest extends IdeaTestCase { }); } + public void testThreads() throws IOException, InterruptedException { + final File ioTempDir = createTempDirectory(); + final File ioPtrBase = new File(ioTempDir, "parent"); + final File ioPtr = new File(ioPtrBase, "f1"); + final File ioSand = new File(ioTempDir, "sand"); + final File ioSandPtr = new File(ioSand, "f2"); + ioSandPtr.getParentFile().mkdirs(); + ioSandPtr.createNewFile(); + ioPtr.getParentFile().mkdirs(); + ioPtr.createNewFile(); + + doVfsRefresh(); + final VirtualFilePointer pointer = createPointerByFile(ioPtr, null); + assertTrue(pointer.isValid()); + final VirtualFile virtualFile = pointer.getFile(); + assertNotNull(virtualFile); + assertTrue(virtualFile.isValid()); + + VirtualFileAdapter listener = new VirtualFileAdapter() { + @Override + public void fileCreated(VirtualFileEvent event) { + doit(pointer); + } + + @Override + public void fileDeleted(VirtualFileEvent event) { + doit(pointer); + } + }; + VirtualFileManager.getInstance().addVirtualFileListener(listener, getTestRootDisposable()); + + System.out.println("------------------"); + + for (int i=0;i<1000;i++) { + assertNotNull(pointer.getFile()); + FileUtil.delete(ioPtrBase); + doVfsRefresh(); + + // ptr is now null, cached as map + + final VirtualFile v = LocalFileSystem.getInstance().findFileByIoFile(ioSandPtr); + new WriteCommandAction.Simple(getProject()) { + @Override + protected void run() throws Throwable { + v.delete(this); //inc FS modCount + LocalFileSystem.getInstance().findFileByIoFile(ioSand).createChildData(this, ioSandPtr.getName()); + } + }.execute().throwException(); + + // ptr is still null + + assertTrue(ioPtrBase.mkdirs()); + assertTrue(ioPtr.createNewFile()); + + doit(pointer); + doVfsRefresh(); + } + } + + private static void doit(final VirtualFilePointer pointer) { + if (((VirtualFilePointerImpl)pointer).isDisposed()) return; + boolean b = JobUtil.invokeConcurrentlyUnderProgress(Collections.nCopies(10, null), new Processor() { + @Override + public boolean process(Object o) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + VirtualFile file = pointer.getFile(); + if (file != null && !file.isValid()) { + throw new IncorrectOperationException("I've caught it. I am that good"); + } + } + }); + + return true; + } + }, false, null); + assertTrue(b); + } + @Override - protected void setUp() throws Exception { - super.setUp(); - myVirtualFilePointerManager = VirtualFilePointerManager.getInstance(); + protected boolean isRunInWriteAction() { + return false; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java index 14857fc3bd50..94b5ea3495e2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.vfs.impl; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; @@ -57,39 +58,41 @@ public class VirtualFilePointerImpl extends UserDataHolderBase implements Virtua @NotNull public String getFileName() { - update(); - - if (myFile != null) { - return myFile.getName(); + Pair result = update(); + VirtualFile file = result.first; + if (file != null) { + return file.getName(); } - int index = myUrl.lastIndexOf('/'); - return index >= 0 ? myUrl.substring(index + 1) : myUrl; + String url = result.second; + int index = url.lastIndexOf('/'); + return index >= 0 ? url.substring(index + 1) : url; } public VirtualFile getFile() { checkDisposed(); - update(); - return myFile; + Pair result = update(); + return result.first; } @NotNull public String getUrl() { //checkDisposed(); no check here since Disposer might want to compute hashcode during dispose() - update(); - return getUrlNoUpdate(); + + Pair result = update(); + return getUrlNoUpdate(result.first, result.second); } - private String getUrlNoUpdate() { - return myUrl == null ? myFile.getUrl() : myUrl; + private static String getUrlNoUpdate(VirtualFile file, String url) { + return url == null ? file.getUrl() : url; } @NotNull public String getPresentableUrl() { checkDisposed(); - update(); + Pair result = update(); - return PathUtil.toPresentableUrl(getUrl()); + return PathUtil.toPresentableUrl(result.second); } private void checkDisposed() { @@ -138,36 +141,42 @@ public class VirtualFilePointerImpl extends UserDataHolderBase implements Virtua } public boolean isValid() { - update(); - return !disposed && myFile != null; + Pair result = update(); + return !disposed && result.first != null; } - void update() { - if (disposed) return; + Pair update() { + if (disposed) return null; + long lastUpdated = myLastUpdated; + String url = myUrl; + VirtualFile file = myFile; long fsModCount = myVirtualFileManager.getModificationCount(); - if (myLastUpdated == fsModCount) return; - myLastUpdated = fsModCount; + if (lastUpdated == fsModCount) return Pair.create(file, url); - if (myFile != null && !myFile.isValid()) { - myUrl = myFile.getUrl(); - myFile = null; + if (file != null && !file.isValid()) { + url = file.getUrl(); + file = null; } - if (myFile == null) { - LOG.assertTrue(myUrl != null, "Both file & url are null"); - myFile = myVirtualFileManager.findFileByUrl(myUrl); - if (myFile != null) { - myUrl = null; + if (file == null) { + LOG.assertTrue(url != null, "Both file & url are null"); + file = myVirtualFileManager.findFileByUrl(url); + if (file != null) { + url = null; } } - else if (!myFile.exists()) { - myUrl = myFile.getUrl(); - myFile = null; + if (file != null && !file.exists()) { + url = file.getUrl(); + file = null; } + myFile = file; + myUrl = url; + myLastUpdated = fsModCount; + return Pair.create(file, url); } @Override public String toString() { - return getUrlNoUpdate(); + return getUrlNoUpdate(myFile, myUrl); } public void dispose() { @@ -178,9 +187,13 @@ public class VirtualFilePointerImpl extends UserDataHolderBase implements Virtua if (TRACE_CREATION) { putUserData(KILL_TRACE, new Throwable()); } - String url = getUrlNoUpdate(); + String url = getUrlNoUpdate(myFile, myUrl); disposed = true; ((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).clearPointerCaches(url, myListener); } } + + public boolean isDisposed() { + return disposed; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java index 7378fa424bb9..0a9551a598b2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -332,9 +332,6 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp } } - //if (myListenerToPointersMap.isEmpty()) { - // System.err.println("All pointers are disposed"); - //} synchronized (myContainers) { if (!myContainers.isEmpty()) { VirtualFilePointerContainerImpl container = myContainers.iterator().next(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index f54878d042d6..2835d4a20f3c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -20,11 +20,13 @@ package com.intellij.openapi.vfs.newvfs.impl; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import com.intellij.openapi.vfs.newvfs.RefreshQueue; 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.containers.ContainerUtil; import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; @@ -41,9 +43,11 @@ import java.util.*; public class VirtualDirectoryImpl extends VirtualFileSystemEntry { private final NewVirtualFileSystem myFS; + + // guarded by this private Object myChildren; // Either HashMap or VFile[] - public VirtualDirectoryImpl(final String name, final VirtualDirectoryImpl parent, final NewVirtualFileSystem fs, final int id) { + public VirtualDirectoryImpl(@NotNull String name, final VirtualDirectoryImpl parent, @NotNull NewVirtualFileSystem fs, final int id) { super(name, parent, id); myFS = fs; } @@ -54,24 +58,34 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - private NewVirtualFile findChild(final String name, final boolean createIfNotFound, boolean ensureCanonicalName) { - final NewVirtualFile result = doFindChild(name, createIfNotFound, ensureCanonicalName); - synchronized (this) { - if (result == null && myChildren instanceof Map) { - ensureAsMap().put(name, NullVirtualFile.INSTANCE); + private NewVirtualFile findChild(@NotNull String name, final boolean createIfNotFound, boolean ensureCanonicalName) { + final VirtualFile result = doFindChild(name, createIfNotFound, ensureCanonicalName); + if (result == NullVirtualFile.INSTANCE) { + return createIfNotFound ? createAndFindChildWithEventFire(name) : null; + } + + if (result == null) { + synchronized (this) { + Map map = asMap(); + if (map != null) { + map.put(name, NullVirtualFile.INSTANCE); + } } } - return result; + return (NewVirtualFile)result; } @Nullable - private NewVirtualFile doFindChild(String name, final boolean createIfNotFound, boolean ensureCanonicalName) { + private VirtualFile doFindChild(@NotNull String name, final boolean createIfNotFound, boolean ensureCanonicalName) { if (name.length() == 0) { return null; } - final VirtualFile[] a = asArray(); + final VirtualFile[] a; + synchronized (this) { + a = asArray(); + } if (a != null) { Object encoded = encodeName(name); byte[] bytes = encoded instanceof byte[] ? (byte[])encoded : null; @@ -89,11 +103,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { file = map.get(name); } - if (file == NullVirtualFile.INSTANCE) { - return createIfNotFound ? createAndFindChildWithEventFire(name) : null; - } - - if (file != null) return (NewVirtualFile)file; + if (file != null) return file; if (ensureCanonicalName) { final NewVirtualFileSystem delegate = getFileSystem(); @@ -131,6 +141,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return name.equalsIgnoreCase(name2); } + @NotNull public VirtualFileSystemEntry createChild(String name, int id) { final VirtualFileSystemEntry child; final NewVirtualFileSystem fs = getFileSystem(); @@ -149,7 +160,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - private NewVirtualFile createAndFindChildWithEventFire(final String name) { + private NewVirtualFile createAndFindChildWithEventFire(@NotNull String name) { final NewVirtualFileSystem delegate = getFileSystem(); VirtualFile fake = new FakeVirtualFile(this, name); if (delegate.exists(fake)) { @@ -164,12 +175,12 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - public NewVirtualFile refreshAndFindChild(final String name) { + public NewVirtualFile refreshAndFindChild(@NotNull String name) { return findChild(name, true, true); } @Nullable - public synchronized NewVirtualFile findChildIfCached(final String name) { + public synchronized NewVirtualFile findChildIfCached(@NotNull String name) { final VirtualFile[] a = asArray(); if (a != null) { Object encoded = encodeName(name); @@ -191,6 +202,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Override + @NotNull public Iterable iterInDbChildren() { return ContainerUtil.iterate(getInDbChildren(), new Condition() { public boolean value(VirtualFile file) { @@ -228,17 +240,19 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return (VirtualFile[])myChildren; } - final int[] childrenIds = ourPersistence.listIds(this); + Pair pair = PersistentFS.listAll(this); + final int[] childrenIds = pair.second; VirtualFile[] children; if (childrenIds.length == 0) { children = EMPTY_ARRAY; } else { children = new VirtualFile[childrenIds.length]; + String[] names = pair.first; final Map map = asMap(); for (int i = 0; i < children.length; i++) { final int childId = childrenIds[i]; - final String name = ourPersistence.getName(childId); + final String name = names[i]; VirtualFile child = map != null ? map.get(name) : null; children[i] = child != null && child != NullVirtualFile.INSTANCE ? child : createChild(name, childId); @@ -293,21 +307,21 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - private synchronized VirtualFile[] asArray() { + private VirtualFile[] asArray() { if (myChildren instanceof VirtualFile[]) return (VirtualFile[])myChildren; return null; } @Nullable @SuppressWarnings({"unchecked"}) - private synchronized Map asMap() { + private Map asMap() { if (myChildren instanceof Map) return (Map)myChildren; return null; } @NotNull @SuppressWarnings({"unchecked"}) - private synchronized Map ensureAsMap() { + private Map ensureAsMap() { Map map; if (myChildren == null) { map = createMap(); @@ -320,7 +334,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return map; } - public synchronized void addChild(VirtualFile file) { + public synchronized void addChild(@NotNull VirtualFile file) { final VirtualFile[] a = asArray(); if (a != null) { myChildren = ArrayUtil.append(a, file); @@ -331,7 +345,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } } - public synchronized void removeChild(VirtualFile file) { + public synchronized void removeChild(@NotNull VirtualFile file) { final VirtualFile[] a = asArray(); if (a != null) { myChildren = ArrayUtil.remove(a, file); @@ -346,7 +360,8 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return myChildren instanceof VirtualFile[]; } - public synchronized List getSuspicousNames() { + @NotNull + public synchronized List getSuspiciousNames() { final Map map = asMap(); if (map == null) return Collections.emptyList(); @@ -379,6 +394,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { return Collections.emptyList(); } + @NotNull private Map createMap() { return getFileSystem().isCaseSensitive() ? new THashMap() @@ -386,14 +402,15 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @TestOnly - public synchronized void cleanupCachedChildren(Set survivors) { + public synchronized void cleanupCachedChildren(@NotNull Set survivors) { if (survivors.contains(this)) { for (VirtualFile file : getCachedChildren()) { if (file instanceof VirtualDirectoryImpl) { ((VirtualDirectoryImpl)file).cleanupCachedChildren(survivors); } } - } else { + } + else { myChildren = null; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 45f859f031c5..3df42df8e973 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -24,6 +24,7 @@ import com.intellij.openapi.Forceable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; @@ -88,7 +89,7 @@ public class FSRecords implements Forceable { private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN"; private static final Object lock = new Object(); - private volatile static int ourLocalModificationCount = 0; + private static volatile int ourLocalModificationCount = 0; private static final int FREE_RECORD_FLAG = 0x100; private static final int ALL_VALID_FLAGS = PersistentFS.ALL_VALID_FLAGS | FREE_RECORD_FLAG; @@ -205,8 +206,8 @@ public class FSRecords implements Forceable { boolean deleted = true; deleted &= FileUtil.delete(getCorruptionMarkerFile()); deleted &= deleteWithSubordinates(namesFile); - deleted &= Storage.deleteFiles(attributesFile.getCanonicalPath()); - deleted &= Storage.deleteFiles(contentsFile.getCanonicalPath()); + deleted &= AbstractStorage.deleteFiles(attributesFile.getCanonicalPath()); + deleted &= AbstractStorage.deleteFiles(contentsFile.getCanonicalPath()); deleted &= deleteWithSubordinates(recordsFile); if (!deleted) { @@ -259,7 +260,12 @@ public class FSRecords implements Forceable { } private static File basePath() { - return new File(PathManager.getSystemPath() + "/caches/"); + return new File(getCachesDir()); + } + + private static String getCachesDir() { + String dir = System.getProperty("caches_dir"); + return dir == null ? PathManager.getSystemPath() + "/caches/" : dir; } private static boolean deleteWithSubordinates(File file) { @@ -280,7 +286,7 @@ public class FSRecords implements Forceable { return ok; } - private static void markDirty() throws IOException { + private static void markDirty() { if (!myDirty) { myDirty = true; myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, CONNECTED_MAGIC); @@ -302,13 +308,8 @@ public class FSRecords implements Forceable { public static void force() { synchronized (lock) { - try { - if (myRecords != null) { - markClean(); - } - } - catch (IOException e) { - LOG.info(e); + if (myRecords != null) { + markClean(); } if (myNames != null) { myNames.force(); @@ -329,12 +330,7 @@ public class FSRecords implements Forceable { final boolean attribsFlushed = myAttributes.flushSome(); final boolean contentsFlushed = myContents.flushSome(); if (attribsFlushed && contentsFlushed) { - try { - markClean(); - } - catch (IOException e) { - // Ignore - } + markClean(); myRecords.force(); } } @@ -345,7 +341,7 @@ public class FSRecords implements Forceable { } - private static int getVersion() throws IOException { + private static int getVersion() { final int recordsVersion = myRecords.getInt(HEADER_VERSION_OFFSET); if (myAttributes.getVersion() != recordsVersion || myContents.getVersion() != recordsVersion) return -1; @@ -356,7 +352,7 @@ public class FSRecords implements Forceable { return myRecords.getLong(HEADER_TIMESTAMP_OFFSET); } - private static void setCurrentVersion() throws IOException { + private static void setCurrentVersion() { myRecords.putInt(HEADER_VERSION_OFFSET, VERSION); myRecords.putLong(HEADER_TIMESTAMP_OFFSET, System.currentTimeMillis()); myAttributes.setVersion(VERSION); @@ -364,7 +360,7 @@ public class FSRecords implements Forceable { myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, SAFELY_CLOSED_MAGIC); } - public static void cleanRecord(final int id) throws IOException { + public static void cleanRecord(final int id) { myRecords.put(id * RECORD_SIZE, ZEROES, 0, RECORD_SIZE); } @@ -376,7 +372,7 @@ public class FSRecords implements Forceable { return myRecords; } - public void dispose() throws IOException { + public static void dispose() throws IOException { synchronized (lock) { refCount--; if (refCount == 0) { @@ -413,7 +409,7 @@ public class FSRecords implements Forceable { } } - private static void markClean() throws IOException { + private static void markClean() { if (myDirty) { myDirty = false; myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, myCorrupted ? CORRUPTED_MAGIC : SAFELY_CLOSED_MAGIC); @@ -449,11 +445,11 @@ public class FSRecords implements Forceable { public FSRecords() { } - public void connect() { + public static void connect() { DbConnection.connect(); } - public long getCreationTimestamp() { + public static long getCreationTimestamp() { synchronized (lock) { return DbConnection.getTimestamp(); } @@ -500,7 +496,7 @@ public class FSRecords implements Forceable { } } - public void deleteRecordRecursively(int id) { + public static void deleteRecordRecursively(int id) { synchronized (lock) { try { DbConnection.markDirty(); @@ -513,7 +509,7 @@ public class FSRecords implements Forceable { } } - private void doDeleteRecursively(final int id) { + private static void doDeleteRecursively(final int id) { for (int subrecord : list(id)) { doDeleteRecursively(subrecord); } @@ -521,7 +517,7 @@ public class FSRecords implements Forceable { deleteRecord(id); } - private void deleteRecord(final int id) { + private static void deleteRecord(final int id) { synchronized (lock) { try { DbConnection.markDirty(); @@ -536,7 +532,7 @@ public class FSRecords implements Forceable { } } - private void deleteContentAndAttributes(int id) throws IOException { + private static void deleteContentAndAttributes(int id) throws IOException { int content_page = getContentRecordId(id); if (content_page != 0) { getContentStorage().releaseRecord(content_page); @@ -555,12 +551,12 @@ public class FSRecords implements Forceable { } } - private void addToFreeRecordsList(int id) throws IOException { + private static void addToFreeRecordsList(int id) { DbConnection.addFreeRecord(id); setFlags(id, FREE_RECORD_FLAG, false); } - public int[] listRoots() throws IOException { + public static int[] listRoots() throws IOException { synchronized (lock) { DbConnection.markDirty(); final DataInputStream input = readAttribute(1, CHILDREN_ATT); @@ -591,7 +587,7 @@ public class FSRecords implements Forceable { return DbConnection.isDirty(); } - public int findRootRecord(String rootUrl) throws IOException { + public static int findRootRecord(String rootUrl) throws IOException { synchronized (lock) { DbConnection.markDirty(); final int root = getNames().enumerate(rootUrl); @@ -641,7 +637,7 @@ public class FSRecords implements Forceable { } } - public void deleteRootRecord(int id) throws IOException { + public static void deleteRootRecord(int id) throws IOException { synchronized (lock) { DbConnection.markDirty(); final DataInputStream input = readAttribute(1, CHILDREN_ATT); @@ -683,7 +679,7 @@ public class FSRecords implements Forceable { } } - public int[] list(int id) { + public static int[] list(int id) { synchronized (lock) { try { final DataInputStream input = readAttribute(id, CHILDREN_ATT); @@ -702,8 +698,30 @@ public class FSRecords implements Forceable { } } } + public static Pair listAll(int parentId) { + synchronized (lock) { + try { + final DataInputStream input = readAttribute(parentId, CHILDREN_ATT); + if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY); - public boolean wereChildrenAccessed(int id) { + final int count = input.readInt(); + final int[] ids = ArrayUtil.newIntArray(count); + final String[] names = ArrayUtil.newStringArray(count); + for (int i = 0; i < count; i++) { + int id = input.readInt(); + ids[i] = id; + names[i] = getName(id); + } + input.close(); + return Pair.create(names, ids); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + } + } + + public static boolean wereChildrenAccessed(int id) { try { synchronized (lock) { return findAttributePage(id, CHILDREN_ATT, false) != 0; @@ -714,7 +732,7 @@ public class FSRecords implements Forceable { } } - public void updateList(int id, int[] children) { + public static void updateList(int id, int[] children) { synchronized (lock) { try { DbConnection.markDirty(); @@ -736,7 +754,7 @@ public class FSRecords implements Forceable { } } - private static void incModCount(int id) throws IOException { + private static void incModCount(int id) { ourLocalModificationCount++; final int count = getModCount() + 1; getRecords().putInt(HEADER_GLOBAL_MODCOUNT_OFFSET, count); @@ -775,7 +793,7 @@ public class FSRecords implements Forceable { } } - public void setParent(int id, int parent) { + public static void setParent(int id, int parent) { if (id == parent) { LOG.error("Cyclic parent/child relations"); return; @@ -805,7 +823,7 @@ public class FSRecords implements Forceable { } } - public void setName(int id, String name) { + public static void setName(int id, String name) { synchronized (lock) { try { DbConnection.markDirty(); @@ -824,7 +842,7 @@ public class FSRecords implements Forceable { } } - public void setFlags(int id, int flags, final boolean markAsChange) { + public static void setFlags(int id, int flags, final boolean markAsChange) { synchronized (lock) { try { if (markAsChange) { @@ -845,7 +863,7 @@ public class FSRecords implements Forceable { } } - public void setLength(int id, long len) { + public static void setLength(int id, long len) { synchronized (lock) { try { DbConnection.markDirty(); @@ -864,7 +882,7 @@ public class FSRecords implements Forceable { } } - public void setTimestamp(int id, long value) { + public static void setTimestamp(int id, long value) { synchronized (lock) { try { DbConnection.markDirty(); @@ -883,23 +901,23 @@ public class FSRecords implements Forceable { } } - private static void setModCount(int id, int value) throws IOException { + private static void setModCount(int id, int value) { putRecordInt(id, MODCOUNT_OFFSET, value); } - private static int getContentRecordId(int fileId) throws IOException { + private static int getContentRecordId(int fileId) { return getRecordInt(fileId, CONTENT_OFFSET); } - private static void setContentRecordId(int id, int value) throws IOException { + private static void setContentRecordId(int id, int value) { putRecordInt(id, CONTENT_OFFSET, value); } - private static int getAttributeRecordId(int id) throws IOException { + private static int getAttributeRecordId(int id) { return getRecordInt(id, ATTREF_OFFSET); } - private static void setAttributeRecordId(int id, int value) throws IOException { + private static void setAttributeRecordId(int id, int value) { putRecordInt(id, ATTREF_OFFSET, value); } @@ -916,7 +934,7 @@ public class FSRecords implements Forceable { } @Nullable - public DataInputStream readContent(int fileId) { + public static DataInputStream readContent(int fileId) { try { int page; synchronized (lock) { @@ -931,7 +949,7 @@ public class FSRecords implements Forceable { } @Nullable - public DataInputStream readContentById(int contentId) { + public static DataInputStream readContentById(int contentId) { try { return getContentStorage().readStream(contentId); } @@ -941,7 +959,7 @@ public class FSRecords implements Forceable { } @Nullable - public DataInputStream readAttribute(int fileId, String attId) { + public static DataInputStream readAttribute(int fileId, String attId) { try { synchronized (attId) { int page; @@ -957,7 +975,7 @@ public class FSRecords implements Forceable { } } - private int findContentPage(int fileId, boolean toWrite) throws IOException { + private static int findContentPage(int fileId, boolean toWrite) throws IOException { checkFileIsValid(fileId); int recordId = getContentRecordId(fileId); @@ -971,7 +989,7 @@ public class FSRecords implements Forceable { return recordId; } - private int findAttributePage(int fileId, String attrId, boolean toWrite) throws IOException { + private static int findAttributePage(int fileId, String attrId, boolean toWrite) throws IOException { checkFileIsValid(fileId); Storage storage = getAttributesStorage(); @@ -1012,13 +1030,13 @@ public class FSRecords implements Forceable { return 0; } - private void checkFileIsValid(int fileId) { + private static void checkFileIsValid(int fileId) { assert fileId > 0 : "assert fileId > 0 failed"; // TODO: This assertion is a bit timey, will remove when bug is caught. assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Trying to find an attribute of deleted page"; } - public int acquireFileContent(int fileId) { + public static int acquireFileContent(int fileId) { try { synchronized (lock) { int record = getContentRecordId(fileId); @@ -1031,7 +1049,7 @@ public class FSRecords implements Forceable { } } - public void releaseContent(int contentId) { + public static void releaseContent(int contentId) { try { getContentStorage().releaseRecord(contentId); } @@ -1040,7 +1058,7 @@ public class FSRecords implements Forceable { } } - public int getContentId(int fileId) { + public static int getContentId(int fileId) { try { synchronized (lock) { return getContentRecordId(fileId); @@ -1052,15 +1070,15 @@ public class FSRecords implements Forceable { } @NotNull - public DataOutputStream writeContent(int fileId, boolean readOnly) { + public static DataOutputStream writeContent(int fileId, boolean readOnly) { return new ContentOutputStream(fileId, readOnly); } - public void writeContent(int fileId, ByteSequence bytes, boolean readOnly) throws IOException { + public static void writeContent(int fileId, ByteSequence bytes, boolean readOnly) throws IOException { new ContentOutputStream(fileId, readOnly).writeBytes(bytes, fileId); } - public int storeUnlinkedContent(byte[] bytes) { + public static int storeUnlinkedContent(byte[] bytes) { try { int recordId = getContentStorage().acquireNewRecord(); AbstractStorage.StorageDataOutput output = getContentStorage().writeStream(recordId); @@ -1074,12 +1092,11 @@ public class FSRecords implements Forceable { } @NotNull - public DataOutputStream writeAttribute(final int fileId, final String attId, boolean fixedSize) { + public static DataOutputStream writeAttribute(final int fileId, final String attId, boolean fixedSize) { return new AttributeOutputStream(fileId, attId, fixedSize); } - private class ContentOutputStream extends BaseOutputStream { - + private static class ContentOutputStream extends BaseOutputStream { private ContentOutputStream(final int fileId, boolean readOnly) { super(fileId, readOnly); } @@ -1095,7 +1112,7 @@ public class FSRecords implements Forceable { } } - private class AttributeOutputStream extends BaseOutputStream { + private static class AttributeOutputStream extends BaseOutputStream { private final String myAttributeId; private AttributeOutputStream(final int fileId, final String attributeId, boolean fixedSize) { @@ -1163,7 +1180,7 @@ public class FSRecords implements Forceable { protected abstract AbstractStorage getStorage(); } - public void dispose() { + public static void dispose() { synchronized (lock) { try { DbConnection.force(); @@ -1180,7 +1197,7 @@ public class FSRecords implements Forceable { } public static void checkSanity() { - long startTime = System.currentTimeMillis(); + //long startTime = System.currentTimeMillis(); synchronized (lock) { final int fileLength = (int)getRecords().length(); assert fileLength % RECORD_SIZE == 0; @@ -1201,7 +1218,7 @@ public class FSRecords implements Forceable { } } - long endTime = System.currentTimeMillis(); + //long endTime = System.currentTimeMillis(); //System.out.println("Sanity check took " + (endTime-startTime) + " ms"); } @@ -1227,26 +1244,15 @@ public class FSRecords implements Forceable { } private static void checkContentsStorageSanity(int id) { - try { - int recordId = getContentRecordId(id); - assert recordId >= 0; - if (recordId > 0) { - getContentStorage().checkSanity(recordId); - } - } - catch (IOException e) { - throw DbConnection.handleError(e); + int recordId = getContentRecordId(id); + assert recordId >= 0; + if (recordId > 0) { + getContentStorage().checkSanity(recordId); } } private static void checkAttributesStorageSanity(int id, IntArrayList usedAttributeRecordIds, IntArrayList validAttributeIds) { - int attributeRecordId; - try { - attributeRecordId = getAttributeRecordId(id); - } - catch (IOException ex) { - throw DbConnection.handleError(ex); - } + int attributeRecordId = getAttributeRecordId(id); assert attributeRecordId >= 0; if (attributeRecordId > 0) { @@ -1267,7 +1273,7 @@ public class FSRecords implements Forceable { final DataInputStream dataInputStream = getAttributesStorage().readStream(attributeRecordId); try { final int streamSize = dataInputStream.available(); - assert (streamSize % 8) == 0; + assert streamSize % 8 == 0; for (int i = 0; i < streamSize / 8; i++) { int attId = dataInputStream.readInt(); int attDataRecordId = dataInputStream.readInt(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java index 5489c0407ccb..21aaa1826b72 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java @@ -23,6 +23,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; @@ -59,7 +60,6 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { public static final long FILE_LENGTH_TO_CACHE_THRESHOLD = 20 * 1024 * 1024; // 20 megabytes - private final FSRecords myRecords; private final MessageBus myEventsBus; private final Map myRoots = new HashMap(); @@ -73,7 +73,6 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { public PersistentFS(MessageBus bus) { myEventsBus = bus; - myRecords = new FSRecords(); /* PropertiesComponent properties = PropertiesComponent.getInstance(); @@ -100,7 +99,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { private void performShutdown() { if (!myShutdownPerformed.getAndSet(Boolean.TRUE)) { LOG.info("VFS dispose started"); - myRecords.dispose(); + FSRecords.dispose(); LOG.info("VFS dispose completed"); } } @@ -112,7 +111,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } public void initComponent() { - myRecords.connect(); + FSRecords.connect(); } public boolean areChildrenLoaded(final VirtualFile dir) { @@ -120,7 +119,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } public long getCreationTimestamp() { - return myRecords.getCreationTimestamp(); + return FSRecords.getCreationTimestamp(); } private static NewVirtualFileSystem getDelegate(VirtualFile file) { @@ -128,25 +127,25 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } public boolean wereChildrenAccessed(final VirtualFile dir) { - return myRecords.wereChildrenAccessed(getFileId(dir)); + return FSRecords.wereChildrenAccessed(getFileId(dir)); } public String[] list(final VirtualFile file) { int id = getFileId(file); + int[] childrenIds = FSRecords.list(id); + String[] names = listPersisted(childrenIds); if (areChildrenLoaded(id)) { - return listPersisted(file); - } - else { - return persistAllChildren(file); + return names; } + Pair pair = persistAllChildren(file, id, Pair.create(names, childrenIds)); + return pair.first; } public String[] listPersisted(final VirtualFile file) { - return listPersisted(getFileId(file)); + return listPersisted(FSRecords.list(getFileId(file))); } - private String[] listPersisted(final int id) { - final int[] childrenIds = myRecords.list(id); + private static String[] listPersisted(int[] childrenIds) { String[] names = ArrayUtil.newStringArray(childrenIds.length); for (int i = 0; i < childrenIds.length; i++) { names[i] = FSRecords.getName(childrenIds[i]); @@ -154,14 +153,15 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return names; } - private String[] persistAllChildren(final VirtualFile file) { - int id = getFileId(file); - String[] currentNames = listPersisted(file); - int[] currentIds = myRecords.list(id); + private static Pair persistAllChildren(final VirtualFile file, int id, Pair current) { + String[] currentNames = current.first; + int[] currentIds = current.second; final NewVirtualFileSystem delegate = getDelegate(file); String[] delegateNames = VfsUtil.filterNames(delegate.list(file)); - if (delegateNames.length == 0 && currentNames.length > 0) return currentNames; + if (delegateNames.length == 0 && currentNames.length > 0) { + return current; + } final String[] names; if (currentNames.length == 0) { @@ -189,21 +189,34 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } } - myRecords.updateList(id, childrenIds); + FSRecords.updateList(id, childrenIds); int flags = FSRecords.getFlags(id); - myRecords.setFlags(id, flags | CHILDREN_CACHED_FLAG, true); + FSRecords.setFlags(id, flags | CHILDREN_CACHED_FLAG, true); - return names; + return Pair.create(names, childrenIds); } - public int[] listIds(VirtualFile parent) { + public static int[] listIds(VirtualFile parent) { final int parentId = getFileId(parent); + int[] ids = FSRecords.list(parentId); if (!areChildrenLoaded(parentId)) { - list(parent); + String[] names = listPersisted(ids); + Pair pair = persistAllChildren(parent, parentId, Pair.create(names, ids)); + return pair.second; } - return myRecords.list(parentId); + return ids; + } + public static Pair listAll(VirtualFile parent) { + final int parentId = getFileId(parent); + + Pair pair = FSRecords.listAll(parentId); + if (!areChildrenLoaded(parentId)) { + return persistAllChildren(parent, parentId, pair); + } + + return pair; } @@ -214,33 +227,33 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { @Nullable public DataInputStream readAttribute(final VirtualFile file, final FileAttribute att) { - return myRecords.readAttribute(getFileId(file), att.getId()); + return FSRecords.readAttribute(getFileId(file), att.getId()); } public DataOutputStream writeAttribute(final VirtualFile file, final FileAttribute att) { - return myRecords.writeAttribute(getFileId(file), att.getId(), att.isFixedSize()); + return FSRecords.writeAttribute(getFileId(file), att.getId(), att.isFixedSize()); } @Nullable - private DataInputStream readContent(VirtualFile file) { - return myRecords.readContent(getFileId(file)); + private static DataInputStream readContent(VirtualFile file) { + return FSRecords.readContent(getFileId(file)); } @Nullable - private DataInputStream readContentById(int contentId) { - return myRecords.readContentById(contentId); + private static DataInputStream readContentById(int contentId) { + return FSRecords.readContentById(contentId); } - private DataOutputStream writeContent(VirtualFile file, boolean readOnly) { - return myRecords.writeContent(getFileId(file), readOnly); + private static DataOutputStream writeContent(VirtualFile file, boolean readOnly) { + return FSRecords.writeContent(getFileId(file), readOnly); } - private void writeContent(VirtualFile file, ByteSequence content, boolean readOnly) throws IOException { - myRecords.writeContent(getFileId(file), content, readOnly); + private static void writeContent(VirtualFile file, ByteSequence content, boolean readOnly) throws IOException { + FSRecords.writeContent(getFileId(file), content, readOnly); } public int storeUnlinkedContent(byte[] bytes) { - return myRecords.storeUnlinkedContent(bytes); + return FSRecords.storeUnlinkedContent(bytes); } public int getModificationCount(final VirtualFile file) { @@ -257,7 +270,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return FSRecords.getModCount(); } - private void copyRecordFromDelegateFS(final int id, final int parentId, final VirtualFile file, NewVirtualFileSystem delegate) { + private static void copyRecordFromDelegateFS(final int id, final int parentId, final VirtualFile file, NewVirtualFileSystem delegate) { if (id == parentId) { LOG.error("Cyclic parent-child relations for file: " + file); return; @@ -271,13 +284,13 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { if (areChildrenLoaded(id)) return; } - myRecords.setParent(id, parentId); - myRecords.setName(id, name); + FSRecords.setParent(id, parentId); + FSRecords.setName(id, name); - myRecords.setTimestamp(id, delegate.getTimeStamp(file)); - myRecords.setFlags(id, (delegate.isDirectory(file) ? IS_DIRECTORY_FLAG : 0) | (delegate.isWritable(file) ? 0 : IS_READ_ONLY), true); + FSRecords.setTimestamp(id, delegate.getTimeStamp(file)); + FSRecords.setFlags(id, (delegate.isDirectory(file) ? IS_DIRECTORY_FLAG : 0) | (delegate.isWritable(file) ? 0 : IS_READ_ONLY), true); - myRecords.setLength(id, -1L); + FSRecords.setLength(id, -1L); // TODO!!!: More attributes? } @@ -313,7 +326,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { public void setTimeStamp(final VirtualFile file, final long modstamp) throws IOException { final int id = getFileId(file); - myRecords.setTimestamp(id, modstamp); + FSRecords.setTimestamp(id, modstamp); getDelegate(file).setTimeStamp(file, modstamp); } @@ -340,7 +353,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final NewVirtualFileSystem delegate = getDelegate(parent); final int parentId = getFileId(parent); - final int[] children = myRecords.list(parentId); + final int[] children = FSRecords.list(parentId); for (final int childId : children) { if (namesEqual(delegate, childName, FSRecords.getName(childId))) return childId; } @@ -349,7 +362,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { if (delegate.exists(fake)) { int child = FSRecords.createRecord(); copyRecordFromDelegateFS(child, parentId, fake, delegate); - myRecords.updateList(parentId, ArrayUtil.append(children, child)); + FSRecords.updateList(parentId, ArrayUtil.append(children, child)); return child; } @@ -362,7 +375,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { long len = FSRecords.getLength(id); if (len == -1) { len = (int)getDelegate(file).getLength(file); - myRecords.setLength(id, len); + FSRecords.setLength(id, len); } return len; @@ -436,12 +449,12 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final byte[] content = delegate.contentsToByteArray(file); ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication(); - if ((!delegate.isReadOnly() || (!application.isInternal() && !application.isUnitTestMode())) && + if ((!delegate.isReadOnly() || !application.isInternal() && !application.isUnitTestMode()) && !noCaching && content.length <= FILE_LENGTH_TO_CACHE_THRESHOLD) { synchronized (INPUT_LOCK) { writeContent(file, new ByteSequence(content), delegate.isReadOnly()); - myRecords.setLength(getFileId(file), content.length); + FSRecords.setLength(getFileId(file), content.length); setFlag(file, MUST_RELOAD_CONTENT, false); } } @@ -490,7 +503,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { synchronized (INPUT_LOCK) { if (getBytesRead() == len) { writeContent(file, new ByteSequence(cache.getInternalBuffer(), 0, cache.size()), readOnly); - myRecords.setLength(getFileId(file), len); + FSRecords.setLength(getFileId(file), len); setFlag(file, MUST_RELOAD_CONTENT, false); } else { @@ -553,15 +566,15 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } public int acquireContent(VirtualFile file) { - return myRecords.acquireFileContent(getFileId(file)); + return FSRecords.acquireFileContent(getFileId(file)); } public void releaseContent(int contentId) { - myRecords.releaseContent(contentId); + FSRecords.releaseContent(contentId); } public int getCurrentContentId(VirtualFile file) { - return myRecords.getContentId(getFileId(file)); + return FSRecords.getContentId(getFileId(file)); } public void moveFile(final Object requestor, final VirtualFile file, final VirtualFile newParent) throws IOException { @@ -622,11 +635,12 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { events = validateEvents(events); - myEventsBus.syncPublisher(VirtualFileManager.VFS_CHANGES).before(events); + BulkFileListener publisher = myEventsBus.syncPublisher(VirtualFileManager.VFS_CHANGES); + publisher.before(events); for (VFileEvent event : events) { applyEvent(event); } - myEventsBus.syncPublisher(VirtualFileManager.VFS_CHANGES).after(events); + publisher.after(events); } public static final Object LOCK = new Object(); @@ -641,7 +655,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } if (root == null) { try { - final int rootId = myRecords.findRootRecord(rootUrl); + final int rootId = FSRecords.findRootRecord(rootUrl); if (basePath.length() > 0) { root = new VirtualDirectoryImpl(basePath, null, fs, rootId); } @@ -819,7 +833,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return "PersistentFS"; } - private void executeCreateChild(final VirtualFile parent, final String name) { + 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)) { @@ -833,10 +847,10 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } } - private void appendIdToParentList(final int parentId, final int childId) { - int[] childrenlist = myRecords.list(parentId); + private static void appendIdToParentList(final int parentId, final int childId) { + int[] childrenlist = FSRecords.list(parentId); childrenlist = ArrayUtil.append(childrenlist, childId); - myRecords.updateList(parentId, childrenlist); + FSRecords.updateList(parentId, childrenlist); } private void executeDelete(final VirtualFile file) { @@ -851,7 +865,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final VirtualFile parent = file.getParent(); final int parentId = parent != null ? getFileId(parent) : 0; - myRecords.deleteRecordRecursively(id); + FSRecords.deleteRecordRecursively(id); if (parentId != 0) { removeIdFromParentList(parentId, id); @@ -864,7 +878,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { synchronized (LOCK) { myRoots.remove(file.getUrl()); try { - myRecords.deleteRootRecord(id); + FSRecords.deleteRootRecord(id); } catch (IOException e) { throw new RuntimeException(e); @@ -884,32 +898,32 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { } } - private void removeIdFromParentList(final int parentId, final int id) { - int[] childList = myRecords.list(parentId); + private static void removeIdFromParentList(final int parentId, final int id) { + int[] childList = FSRecords.list(parentId); childList = ArrayUtil.remove(childList, ArrayUtil.indexOf(childList, id)); - myRecords.updateList(parentId, childList); + FSRecords.updateList(parentId, childList); } - private void executeRename(final VirtualFile file, final String newName) { + private static void executeRename(final VirtualFile file, final String newName) { ((VirtualFileSystemEntry)file).setName(newName); final int id = getFileId(file); - myRecords.setName(id, newName); + FSRecords.setName(id, newName); } - private void executeSetWritable(final VirtualFile file, final boolean writableFlag) { + private static void executeSetWritable(final VirtualFile file, final boolean writableFlag) { setFlag(file, IS_READ_ONLY, !writableFlag); } - private void setFlag(VirtualFile file, int mask, boolean value) { + private static void setFlag(VirtualFile file, int mask, boolean value) { setFlag(getFileId(file), mask, value); } - private void setFlag(final int id, final int mask, final boolean value) { + private static void setFlag(final int id, final int mask, final boolean value) { int oldFlags = FSRecords.getFlags(id); int flags = value ? oldFlags | mask : oldFlags & ~mask; if (oldFlags != flags) { - myRecords.setFlags(id, flags, true); + FSRecords.setFlags(id, flags, true); } } @@ -917,24 +931,24 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return (FSRecords.getFlags(getFileId(file)) & mask) != 0; } - private void executeTouch(final VirtualFile file, boolean reloadContentFromDelegate, long newModificationStamp) { + private static void executeTouch(final VirtualFile file, boolean reloadContentFromDelegate, long newModificationStamp) { if (reloadContentFromDelegate) { setFlag(file, MUST_RELOAD_CONTENT, true); } final NewVirtualFileSystem delegate = getDelegate(file); - myRecords.setLength(getFileId(file), delegate.getLength(file)); - myRecords.setTimestamp(getFileId(file), delegate.getTimeStamp(file)); + FSRecords.setLength(getFileId(file), delegate.getLength(file)); + FSRecords.setTimestamp(getFileId(file), delegate.getTimeStamp(file)); ((NewVirtualFile)file).setModificationStamp(newModificationStamp); } @SuppressWarnings({"UnusedDeclaration"}) - private void executeCopy(final VirtualFile from, final VirtualFile newParent, final String copyName) { + private static void executeCopy(final VirtualFile from, final VirtualFile newParent, final String copyName) { executeCreateChild(newParent, copyName); } - private void executeMove(final VirtualFile what, final VirtualFile newParent) { + private static void executeMove(final VirtualFile what, final VirtualFile newParent) { final int whatId = getFileId(what); final int newParentId = getFileId(newParent); final int oldParentId = getFileId(what.getParent()); @@ -943,7 +957,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { appendIdToParentList(newParentId, whatId); ((VirtualFileSystemEntry)what).setParent(newParent); - myRecords.setParent(whatId, newParentId); + FSRecords.setParent(whatId, newParentId); } public String getName(final int id) { @@ -953,7 +967,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { public void cleanPersistedContents() { try { - final int[] roots = myRecords.listRoots(); + final int[] roots = FSRecords.listRoots(); for (int root : roots) { cleanPersistedContentsRecursively(root); } @@ -965,7 +979,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { private void cleanPersistedContentsRecursively(int id) { if (isDirectory(id)) { - for (int child : myRecords.list(id)) { + for (int child : FSRecords.list(id)) { cleanPersistedContentsRecursively(child); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 3cf55b766c6e..6f00cb6b4e17 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -110,7 +110,7 @@ public class RefreshWorker { } } - final List names = dir.getSuspicousNames(); + final List names = dir.getSuspiciousNames(); for (String name : names) { if (name.length() == 0) continue;