From b3760f58e6419a83aada65aab36f2a2426e60ddf Mon Sep 17 00:00:00 2001 From: SquidDev Date: Mon, 1 May 2017 16:45:41 +0100 Subject: [PATCH] Performance improvements to fs.find If the path includes no wildcards then it just checks it exists. If it does, instead of scanning the entire tree, it works out the last directory before the wildcard and starts scanning from there. Closes #89 --- .../core/filesystem/FileSystem.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java index 6f416466d..31446be0d 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java @@ -466,9 +466,25 @@ public synchronized String[] find( String wildPath ) throws FileSystemException { // Match all the files on the system wildPath = sanitizePath( wildPath, true ); + + // If we don't have a wildcard at all just check the file exists + int starIndex = wildPath.indexOf( '*' ); + if( starIndex == -1 ) + { + return exists( wildPath ) ? new String[]{wildPath} : new String[0]; + } + + // Find the all non-wildcarded directories. For instance foo/bar/baz* -> foo/bar + int prevDir = wildPath.substring( 0, starIndex ).lastIndexOf( '/' ); + String startDir = prevDir == -1 ? "" : wildPath.substring( 0, prevDir ); + + // If this isn't a directory then just abort + if( !isDir( startDir ) ) return new String[0]; + + // Scan as normal, starting from this directory Pattern wildPattern = Pattern.compile( "^\\Q" + wildPath.replaceAll( "\\*", "\\\\E[^\\\\/]*\\\\Q" ) + "\\E$" ); List matches = new ArrayList(); - findIn( "", matches, wildPattern ); + findIn( startDir, matches, wildPattern ); // Return matches String[] array = new String[ matches.size() ];