mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
make VfsUtilPerformanceTest.PersistentFS_performance_ofManyFilesCreateDelete less dependent of native FS performance
This commit is contained in:
@@ -30,10 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -65,14 +62,23 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
return parentItem.findChild(file.getName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FSDir convertDirectory(@NotNull VirtualFile parent) {
|
||||
final FSItem fsItem = convert(parent);
|
||||
if (fsItem == null) {
|
||||
FSRecords.invalidateCaches();
|
||||
throw new IllegalStateException("cannot find parent directory: " + parent.getPath());
|
||||
}
|
||||
assert fsItem.isDirectory() : "parent is not a directory: " + parent.getPath();
|
||||
|
||||
return (FSDir)fsItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile parent, @NotNull String dir) throws IOException {
|
||||
final FSItem fsItem = convert(parent);
|
||||
assert fsItem != null && fsItem.isDirectory();
|
||||
|
||||
final FSDir fsDir = (FSDir)fsItem;
|
||||
final FSItem existingDir = fsDir.findChild(dir);
|
||||
FSDir fsDir = convertDirectory(parent);
|
||||
FSItem existingDir = fsDir.findChild(dir);
|
||||
if (existingDir == null) {
|
||||
fsDir.addChild(new FSDir(fsDir, dir));
|
||||
}
|
||||
@@ -85,15 +91,8 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile parent, @NotNull String file) throws IOException {
|
||||
final FSItem fsItem = convert(parent);
|
||||
if (fsItem == null) {
|
||||
FSRecords.invalidateCaches();
|
||||
throw new IllegalStateException("cannot find parent directory: " + parent.getPath());
|
||||
}
|
||||
assert fsItem.isDirectory() : "parent is not a directory: " + parent.getPath();
|
||||
|
||||
final FSDir fsDir = (FSDir)fsItem;
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile parent, @NotNull String file) {
|
||||
FSDir fsDir = convertDirectory(parent);
|
||||
|
||||
assert fsDir.findChild(file) == null : "File " + file + " already exists in " + parent.getPath();
|
||||
fsDir.addChild(new FSFile(fsDir, file));
|
||||
@@ -101,6 +100,11 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
return new FakeVirtualFile(parent, file);
|
||||
}
|
||||
|
||||
@Nullable public VirtualFile findModelChild(@NotNull VirtualFile parent, @NotNull String name) {
|
||||
FSItem child = convertDirectory(parent).findChild(name);
|
||||
return child == null ? null : new FakeVirtualFile(parent, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor,
|
||||
@@ -111,7 +115,7 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(final Object requestor, @NotNull final VirtualFile file) throws IOException {
|
||||
public void deleteFile(final Object requestor, @NotNull final VirtualFile file) {
|
||||
final FSItem fsItem = convert(file);
|
||||
if (fsItem == null) {
|
||||
FSRecords.invalidateCaches();
|
||||
@@ -137,7 +141,7 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException {
|
||||
public void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) {
|
||||
final FSItem fsItem = convert(file);
|
||||
assert fsItem != null;
|
||||
fsItem.setName(newName);
|
||||
@@ -195,7 +199,7 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWritable(@NotNull final VirtualFile file, final boolean writableFlag) throws IOException {
|
||||
public void setWritable(@NotNull final VirtualFile file, final boolean writableFlag) {
|
||||
final FSItem fsItem = convert(file);
|
||||
assert fsItem != null;
|
||||
fsItem.myWritable = writableFlag;
|
||||
@@ -266,7 +270,9 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
void setName(@NotNull String name) {
|
||||
myParent.myChildren.remove(myName);
|
||||
myName = name;
|
||||
myParent.myChildren.put(name, this);
|
||||
}
|
||||
|
||||
public FSDir getParent() {
|
||||
@@ -285,7 +291,7 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
private static class FSDir extends FSItem {
|
||||
private final List<FSItem> myChildren = new ArrayList<>();
|
||||
private final Map<String, FSItem> myChildren = new LinkedHashMap<>();
|
||||
|
||||
FSDir(@Nullable FSDir parent, @NotNull String name) {
|
||||
super(parent, name);
|
||||
@@ -294,13 +300,7 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
@Override
|
||||
@Nullable
|
||||
public FSItem findChild(final String name) {
|
||||
for (FSItem child : myChildren) {
|
||||
if (name.equals(child.myName)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return myChildren.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -309,24 +309,20 @@ public class TempFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
|
||||
void addChild(@NotNull FSItem item) {
|
||||
myChildren.add(item);
|
||||
myChildren.put(item.myName, item);
|
||||
}
|
||||
|
||||
void removeChild(@NotNull FSItem fsItem) {
|
||||
if (fsItem.myName.equals("src") && getParent() == null) {
|
||||
throw new RuntimeException("removing src directory");
|
||||
}
|
||||
myChildren.remove(fsItem);
|
||||
myChildren.remove(fsItem.myName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] list() {
|
||||
String[] names = ArrayUtil.newStringArray(myChildren.size());
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = myChildren.get(i).myName;
|
||||
}
|
||||
return names;
|
||||
return ArrayUtil.toStringArray(myChildren.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-5
@@ -17,6 +17,8 @@ package com.intellij.openapi.vfs;
|
||||
|
||||
import com.intellij.concurrency.JobLauncher;
|
||||
import com.intellij.concurrency.JobSchedulerImpl;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -24,6 +26,7 @@ import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.IoTestUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.ManagingFS;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
|
||||
@@ -43,6 +46,7 @@ import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.util.TimeoutUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -279,10 +283,11 @@ public class VfsUtilPerformanceTest extends BareTestFixtureTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void PersistentFS_performance_ofManyFilesCreateDelete() throws Exception {
|
||||
public void PersistentFS_performance_ofManyFilesCreateDelete() {
|
||||
int N = 100_000;
|
||||
List<VFileEvent> events = new ArrayList<>(N);
|
||||
VirtualDirectoryImpl temp = (VirtualDirectoryImpl)PlatformTestUtil.notNull(LocalFileSystem.getInstance().findFileByIoFile(myTempDir.newFolder()));
|
||||
VirtualDirectoryImpl temp = createTempFsDirectory();
|
||||
|
||||
UIUtil.invokeAndWaitIfNeeded((Runnable)() -> {
|
||||
PlatformTestUtil.startPerformanceTest("many files creations", 10000, () -> {
|
||||
assertEquals(N, events.size());
|
||||
@@ -296,7 +301,7 @@ public class VfsUtilPerformanceTest extends BareTestFixtureTestCase {
|
||||
processEvents(events);
|
||||
}
|
||||
eventsForCreating(events, N, temp);
|
||||
assertEquals(N, new File(temp.getPath()).listFiles().length); // do not call getChildren which caches everything
|
||||
assertEquals(N, TempFileSystem.getInstance().list(temp).length); // do not call getChildren which caches everything
|
||||
})
|
||||
.assertTiming();
|
||||
|
||||
@@ -315,22 +320,45 @@ public class VfsUtilPerformanceTest extends BareTestFixtureTestCase {
|
||||
processEvents(events);
|
||||
}
|
||||
eventsForDeleting(events, temp);
|
||||
assertEquals(N, new File(temp.getPath()).listFiles().length); // do not call getChildren which caches everything
|
||||
assertEquals(N, TempFileSystem.getInstance().list(temp).length); // do not call getChildren which caches everything
|
||||
})
|
||||
.assertTiming();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private VirtualDirectoryImpl createTempFsDirectory() {
|
||||
VirtualDirectoryImpl temp = new WriteAction<VirtualDirectoryImpl>(){
|
||||
@Override
|
||||
protected void run(@NotNull Result<VirtualDirectoryImpl> result) throws Throwable {
|
||||
result.setResult((VirtualDirectoryImpl)TempFileSystem.getInstance().findFileByPath("/").createChildDirectory(this, "temp"));
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
Disposer.register(getTestRootDisposable(), () -> {
|
||||
try {
|
||||
WriteAction.run(() -> temp.delete(this));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
return temp;
|
||||
}
|
||||
|
||||
private static void processEvents(List<VFileEvent> events) {
|
||||
WriteCommandAction.runWriteCommandAction(null, () -> PersistentFS.getInstance().processEvents(events));
|
||||
}
|
||||
|
||||
private void eventsForCreating(List<VFileEvent> events, int N, VirtualDirectoryImpl temp) {
|
||||
events.clear();
|
||||
TempFileSystem fs = TempFileSystem.getInstance();
|
||||
IntStream.range(0, N)
|
||||
.mapToObj(i -> new VFileCreateEvent(this, temp, i + ".txt", false, false))
|
||||
.peek(event -> FileUtil.createIfDoesntExist(new File(event.getPath())))
|
||||
.peek(event -> {
|
||||
if (fs.findModelChild(temp, event.getChildName()) == null) {
|
||||
fs.createChildFile(this, temp, event.getChildName());
|
||||
}
|
||||
})
|
||||
.forEach(events::add);
|
||||
List<CharSequence> names = events.stream().map(e -> ((VFileCreateEvent)e).getChildName()).collect(Collectors.toList());
|
||||
temp.removeChildren(new TIntHashSet(), names);
|
||||
|
||||
Reference in New Issue
Block a user