Repository: cassandra Updated Branches: refs/heads/trunk b59b26ba5 -> 6312f3355
Improve performance of the folderSize function patch by briareus; reviewed by Stefania for CASSANDRA-10677 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6312f335 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6312f335 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6312f335 Branch: refs/heads/trunk Commit: 6312f33559b3e66b5e4e2573a776eda0fc8e67dc Parents: b59b26b Author: Stefania Alborghetti <stefania.alborghe...@datastax.com> Authored: Tue Nov 17 10:40:19 2015 +0800 Committer: Sylvain Lebresne <sylv...@datastax.com> Committed: Tue Nov 17 12:09:21 2015 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../org/apache/cassandra/io/util/FileUtils.java | 30 +++++++---- .../apache/cassandra/io/util/FileUtilsTest.java | 52 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/6312f335/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 0a7fb2d..b466e70 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.2 + * Improve performance of the folderSize function (CASSANDRA-10677) * Add support for type casting in selection clause (CASSANDRA-10310) * Added graphing option to cassandra-stress (CASSANDRA-7918) * Abort in-progress queries that time out (CASSANDRA-7392) http://git-wip-us.apache.org/repos/asf/cassandra/blob/6312f335/src/java/org/apache/cassandra/io/util/FileUtils.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/io/util/FileUtils.java b/src/java/org/apache/cassandra/io/util/FileUtils.java index 46f2de5..d982e15 100644 --- a/src/java/org/apache/cassandra/io/util/FileUtils.java +++ b/src/java/org/apache/cassandra/io/util/FileUtils.java @@ -23,6 +23,7 @@ import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import java.text.DecimalFormat; import java.util.Arrays; import java.util.Collections; @@ -518,25 +519,34 @@ public class FileUtils break; } } + /** * Get the size of a directory in bytes - * @param directory The directory for which we need size. + * @param folder The directory for which we need size. * @return The size of the directory */ - public static long folderSize(File directory) + public static long folderSize(File folder) { - long length = 0; - for (File file : directory.listFiles()) + final long [] sizeArr = {0L}; + try { - if (file.isFile()) - length += file.length(); - else - length += folderSize(file); + Files.walkFileTree(folder.toPath(), new SimpleFileVisitor<Path>() + { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + { + sizeArr[0] += attrs.size(); + return FileVisitResult.CONTINUE; + } + }); } - return length; + catch (IOException e) + { + logger.error("Error while getting {} folder size. {}", folder, e); + } + return sizeArr[0]; } - public static void copyTo(DataInput in, OutputStream out, int length) throws IOException { byte[] buffer = new byte[64 * 1024]; http://git-wip-us.apache.org/repos/asf/cassandra/blob/6312f335/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java b/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java index 7110504..ee33107 100644 --- a/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java +++ b/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java @@ -20,11 +20,20 @@ package org.apache.cassandra.io.util; import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; import java.nio.charset.Charset; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; import org.junit.Test; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.cql3.CQLTester; +import org.apache.cassandra.schema.SchemaKeyspace; +import org.apache.cassandra.utils.FBUtilities; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -52,4 +61,47 @@ public class FileUtilsTest assertEquals(0, b.length); } + @Test + public void testFolderSize() throws Exception + { + File folder = createFolder(Paths.get(DatabaseDescriptor.getAllDataFileLocations()[0], "testFolderSize")); + folder.deleteOnExit(); + + File childFolder = createFolder(Paths.get(folder.getPath(), "child")); + + File[] files = { + createFile(new File(folder, "001"), 10000), + createFile(new File(folder, "002"), 1000), + createFile(new File(folder, "003"), 100), + createFile(new File(childFolder, "001"), 1000), + createFile(new File(childFolder, "002"), 2000), + }; + + assertEquals(0, FileUtils.folderSize(new File(folder, "i_dont_exist"))); + assertEquals(files[0].length(), FileUtils.folderSize(files[0])); + + long size = FileUtils.folderSize(folder); + assertEquals(Arrays.stream(files).mapToLong(f -> f.length()).sum(), size); + } + + private File createFolder(Path path) + { + File folder = path.toFile(); + FileUtils.createDirectory(folder); + return folder; + } + + private File createFile(File file, long size) + { + try + { + RandomAccessFile f = new RandomAccessFile(file, "rw"); + f.setLength(size); + } + catch (Exception e) + { + System.err.println(e); + } + return file; + } }