GP-4456 Significantly improved shared project directory performance when directories contain a very large number of files.

This commit is contained in:
ghidra1
2024-03-25 18:56:02 -04:00
parent 79afe5a702
commit ea8357348e
10 changed files with 187 additions and 130 deletions

View File

@@ -74,6 +74,14 @@ public interface FileSystem {
*/
public String[] getItemNames(String folderPath) throws IOException;
/**
* Returns a list of the folder items contained in the given folder.
* @param folderPath the path of the folder.
* @return a list of folder items.
* @throws IOException
*/
public FolderItem[] getItems(String folderPath) throws IOException;
/**
* Returns the FolderItem in the given folder with the given name
* @param folderPath the folder path containing the item.
@@ -108,8 +116,8 @@ public interface FileSystem {
* all alphanumerics
* @throws IOException thrown if an IO error occurs.
*/
public void createFolder(String parentPath, String folderName) throws InvalidNameException,
IOException;
public void createFolder(String parentPath, String folderName)
throws InvalidNameException, IOException;
/**
* Create a new database item within the specified parent folder using the contents
@@ -133,8 +141,8 @@ public interface FileSystem {
*/
public DatabaseItem createDatabase(String parentPath, String name, String fileID,
BufferFile bufferFile, String comment, String contentType, boolean resetDatabaseId,
TaskMonitor monitor, String user) throws InvalidNameException, IOException,
CancelledException;
TaskMonitor monitor, String user)
throws InvalidNameException, IOException, CancelledException;
/**
* Create a new empty database item within the specified parent folder.
@@ -176,8 +184,8 @@ public interface FileSystem {
* @throws CancelledException if cancelled by monitor
*/
public DataFileItem createDataFile(String parentPath, String name, InputStream istream,
String comment, String contentType, TaskMonitor monitor) throws InvalidNameException,
IOException, CancelledException;
String comment, String contentType, TaskMonitor monitor)
throws InvalidNameException, IOException, CancelledException;
/**
* Creates a new file item from a packed file.
@@ -195,8 +203,8 @@ public interface FileSystem {
* @throws CancelledException if cancelled by monitor
*/
public FolderItem createFile(String parentPath, String name, File packedFile,
TaskMonitor monitor, String user) throws InvalidNameException, IOException,
CancelledException;
TaskMonitor monitor, String user)
throws InvalidNameException, IOException, CancelledException;
/**
* Delete the specified folder.

View File

@@ -60,9 +60,8 @@ public interface FolderItem {
/**
* Return the file ID if one has been established or null
* @throws IOException thrown if IO or access error occurs
*/
String getFileID() throws IOException;
String getFileID();
/**
* Assign a new file-ID to this local non-versioned file.
@@ -288,8 +287,8 @@ public interface FolderItem {
* @throws IOException
* @throws CancelledException if monitor cancels operation
*/
public void output(File outputFile, int version, TaskMonitor monitor) throws IOException,
CancelledException;
public void output(File outputFile, int version, TaskMonitor monitor)
throws IOException, CancelledException;
/**
* Returns this instance after refresh or null if item no longer exists

View File

@@ -604,9 +604,8 @@ public class IndexedLocalFileSystem extends LocalFileSystem {
deallocateItemStorage(parentPath, name);
}
finally {
Msg.warn(this,
"Detected orphaned project file " + conflictedItemStorageName + ": " +
getPath(parentPath, name));
Msg.warn(this, "Detected orphaned project file " + conflictedItemStorageName +
": " + getPath(parentPath, name));
}
}
@@ -893,8 +892,7 @@ public class IndexedLocalFileSystem extends LocalFileSystem {
}
@Override
protected String[] getItemNames(String folderPath, boolean includeHiddenFiles)
throws IOException {
public String[] getItemNames(String folderPath, boolean includeHiddenFiles) throws IOException {
if (readOnly) {
refreshReadOnlyIndex();
}

View File

@@ -134,7 +134,8 @@ public class IndexedV1LocalFileSystem extends IndexedLocalFileSystem {
}
@Override
public FolderItem getItem(String fileID) throws IOException, UnsupportedOperationException {
public LocalFolderItem getItem(String fileID)
throws IOException, UnsupportedOperationException {
checkDisposed();
if (fileIdMap == null) {
return null;

View File

@@ -366,13 +366,9 @@ public abstract class LocalFileSystem implements FileSystem {
protected abstract void deallocateItemStorage(String folderPath, String itemName)
throws IOException;
protected abstract String[] getItemNames(String folderPath, boolean includeHiddenFiles)
public abstract String[] getItemNames(String folderPath, boolean includeHiddenFiles)
throws IOException;
/**
*
* @see ghidra.framework.store.FileSystem#getItemNames(java.lang.String)
*/
@Override
public synchronized String[] getItemNames(String folderPath) throws IOException {
return getItemNames(folderPath, false);
@@ -407,10 +403,21 @@ public abstract class LocalFileSystem implements FileSystem {
}
@Override
public FolderItem getItem(String fileID) throws IOException, UnsupportedOperationException {
public LocalFolderItem getItem(String fileID)
throws IOException, UnsupportedOperationException {
throw new UnsupportedOperationException("getItem by File-ID");
}
@Override
public LocalFolderItem[] getItems(String folderPath) throws IOException {
String[] itemNames = getItemNames(folderPath, false);
LocalFolderItem[] folderItems = new LocalFolderItem[itemNames.length];
for (int i = 0; i < itemNames.length; i++) {
folderItems[i] = getItem(folderPath, itemNames[i]);
}
return folderItems;
}
@Override
public synchronized LocalDatabaseItem createDatabase(String parentPath, String name,
String fileID, BufferFile bufferFile, String comment, String contentType,
@@ -729,7 +736,7 @@ public abstract class LocalFileSystem implements FileSystem {
if (folderPath.length() == 1) {
return;
}
String[] items = getItemNames(folderPath);
String[] items = getItemNames(folderPath, false);
if (items.length > 0) {
return;
}

View File

@@ -140,8 +140,7 @@ public class MangledLocalFileSystem extends LocalFileSystem {
// }
@Override
protected String[] getItemNames(String folderPath, boolean includeHiddenFiles)
throws IOException {
public String[] getItemNames(String folderPath, boolean includeHiddenFiles) throws IOException {
File dir = getFile(folderPath);
File[] dirList = dir.listFiles();
@@ -294,8 +293,7 @@ public class MangledLocalFileSystem extends LocalFileSystem {
*/
@Override
public synchronized void renameFolder(String parentPath, String folderName,
String newFolderName)
throws InvalidNameException, IOException {
String newFolderName) throws InvalidNameException, IOException {
if (readOnly) {
throw new ReadOnlyException();
@@ -440,16 +438,14 @@ public class MangledLocalFileSystem extends LocalFileSystem {
cleanupAfterConstruction(); // remove all temporary content
File tmpRoot =
new File(root.getCanonicalFile().getParentFile(), HIDDEN_DIR_PREFIX + '.' +
root.getName());
File tmpRoot = new File(root.getCanonicalFile().getParentFile(),
HIDDEN_DIR_PREFIX + '.' + root.getName());
if (tmpRoot.exists() || !tmpRoot.mkdir()) {
throw new IOException("Failed to create data directory: " + tmpRoot);
}
IndexedV1LocalFileSystem indexedFs =
new IndexedV1LocalFileSystem(tmpRoot.getAbsolutePath(), isVersioned, false, false,
true);
IndexedV1LocalFileSystem indexedFs = new IndexedV1LocalFileSystem(tmpRoot.getAbsolutePath(),
isVersioned, false, false, true);
migrationInProgress = true;
migrateFolder(SEPARATOR, indexedFs);
@@ -474,7 +470,7 @@ public class MangledLocalFileSystem extends LocalFileSystem {
indexedFs.createFolder(folderPath, name);
migrateFolder(getPath(folderPath, name), indexedFs);
}
for (String name : getItemNames(folderPath)) {
for (String name : getItemNames(folderPath, false)) {
LocalFolderItem item = getItem(folderPath, name);
indexedFs.migrateItem(item);
}

View File

@@ -108,6 +108,19 @@ public class RemoteFileSystem implements FileSystem, RemoteAdapterListener {
return names;
}
@Override
public FolderItem[] getItems(String folderPath) throws IOException {
RepositoryItem[] items = repository.getItemList(folderPath);
FolderItem[] folderItems = new FolderItem[items.length];
for (int i = 0; i < items.length; i++) {
if (items[i].getItemType() != RepositoryItem.DATABASE) {
throw new IOException("Unsupported file type");
}
folderItems[i] = new RemoteDatabaseItem(repository, items[i]);
}
return folderItems;
}
@Override
public synchronized FolderItem getItem(String folderPath, String name) throws IOException {
RepositoryItem item = repository.getItem(folderPath, name);