forked from j62/ctbrec
1
0
Fork 0

Improve directory size update performance

Use NIO Files.walkFileTree() instead of IO File.ListFiles() API.
Speed improvement was ~6.1s -> ~4.4s on my recordings list.

TODO: implement more intelligent refresh.
This commit is contained in:
ctbrec-contrib-01 2020-03-03 21:39:36 +07:00 committed by 0xboobface
parent 2eb1b17513
commit e333722522
2 changed files with 37 additions and 10 deletions

View File

@ -1,18 +1,31 @@
package ctbrec;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.EnumSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.event.EventBusHolder;
import ctbrec.event.RecordingStateChangedEvent;
import ctbrec.recorder.download.Download;
public class Recording implements Serializable {
private static final transient Logger LOG = LoggerFactory.getLogger(Recording.class);
private Model model;
private transient Download download;
private Instant startDate;
@ -216,17 +229,26 @@ public class Recording implements Serializable {
}
private long getDirectorySize(File dir) {
long size = 0;
if (dir.exists()) {
File[] files = dir.listFiles();
if (files == null) {
return 0;
}
for (File file : files) {
size += file.length();
}
final long[] size = { 0 };
int maxDepth = 1; // Don't expect subdirs, so don't even try
try {
Files.walkFileTree(dir.toPath(), EnumSet.noneOf(FileVisitOption.class), maxDepth, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
size[0] += attrs.size();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
// Ignore file access issues
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
LOG.error("Couldn't determine size of recording {}", this, e);
}
return size;
return size[0];
}
public void refresh() {

View File

@ -7,6 +7,7 @@ import static java.nio.file.StandardOpenOption.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@ -135,9 +136,13 @@ public class RecordingManager {
public List<Recording> getAll() {
recordingsLock.lock();
try {
Instant start = Instant.now();
for (Recording recording : recordings) {
recording.refresh();
}
Instant finish = Instant.now();
long timeElapsed = Duration.between(start, finish).toMillis();
LOG.trace("Recordings list refreshed in {} ms", timeElapsed);
return new ArrayList<>(recordings);
} finally {
recordingsLock.unlock();