From 68762fe84c1eff4f3ce32f23c01c597fc408222d Mon Sep 17 00:00:00 2001 From: SquidDev Date: Thu, 9 Apr 2020 22:06:53 +0100 Subject: [PATCH] Switch FileMount to use Files.walkFileTree This means we are already provided with file attributes, which halfs[^1] the time taken to scan folders. [^1]: This dropped the fastest scan time from ~1.3s to ~0.6. It's by no means a perfect benchmark, but this is still an obvious improvement. --- .../core/filesystem/FileMount.java | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileMount.java b/src/main/java/dan200/computercraft/core/filesystem/FileMount.java index 13cf9b062..9cf1ecd3e 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileMount.java @@ -6,6 +6,7 @@ package dan200.computercraft.core.filesystem; import com.google.common.collect.Sets; +import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.filesystem.FileOperationException; import dan200.computercraft.api.filesystem.IWritableMount; @@ -13,9 +14,7 @@ import javax.annotation.Nonnull; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.*; -import java.nio.file.Files; -import java.nio.file.OpenOption; -import java.nio.file.StandardOpenOption; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; import java.util.List; @@ -404,23 +403,46 @@ public class FileMount implements IWritableMount } } + private static class Visitor extends SimpleFileVisitor + { + long size; + + @Override + public FileVisitResult preVisitDirectory( Path dir, BasicFileAttributes attrs ) + { + size += MINIMUM_FILE_SIZE; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile( Path file, BasicFileAttributes attrs ) + { + size += Math.max( attrs.size(), MINIMUM_FILE_SIZE ); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed( Path file, IOException exc ) + { + ComputerCraft.log.error( "Error computing file size for {}", file, exc ); + return FileVisitResult.CONTINUE; + } + } + private static long measureUsedSpace( File file ) { if( !file.exists() ) return 0; - if( file.isDirectory() ) + try { - long size = MINIMUM_FILE_SIZE; - String[] contents = file.list(); - for( String content : contents ) - { - size += measureUsedSpace( new File( file, content ) ); - } - return size; + Visitor visitor = new Visitor(); + Files.walkFileTree( file.toPath(), visitor ); + return visitor.size; } - else + catch( IOException e ) { - return Math.max( file.length(), MINIMUM_FILE_SIZE ); + ComputerCraft.log.error( "Error computing file size for {}", file, e ); + return 0; } } }