mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-4456 Significantly improved shared project directory performance when directories contain a very large number of files.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user