Improve performance of the folderSize function

patch by briareus; reviewed by Stefania for CASSANDRA-10677
This commit is contained in:
Stefania Alborghetti 2015-11-17 10:40:19 +08:00 committed by Sylvain Lebresne
parent b59b26ba5b
commit 6312f33559
3 changed files with 73 additions and 10 deletions

View File

@ -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)

View File

@ -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];

View File

@ -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;
}
}