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:
parent
2eb1b17513
commit
e333722522
|
@ -1,18 +1,31 @@
|
||||||
package ctbrec;
|
package ctbrec;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
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.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ctbrec.event.EventBusHolder;
|
import ctbrec.event.EventBusHolder;
|
||||||
import ctbrec.event.RecordingStateChangedEvent;
|
import ctbrec.event.RecordingStateChangedEvent;
|
||||||
import ctbrec.recorder.download.Download;
|
import ctbrec.recorder.download.Download;
|
||||||
|
|
||||||
public class Recording implements Serializable {
|
public class Recording implements Serializable {
|
||||||
|
private static final transient Logger LOG = LoggerFactory.getLogger(Recording.class);
|
||||||
|
|
||||||
private Model model;
|
private Model model;
|
||||||
private transient Download download;
|
private transient Download download;
|
||||||
private Instant startDate;
|
private Instant startDate;
|
||||||
|
@ -216,17 +229,26 @@ public class Recording implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getDirectorySize(File dir) {
|
private long getDirectorySize(File dir) {
|
||||||
long size = 0;
|
final long[] size = { 0 };
|
||||||
if (dir.exists()) {
|
int maxDepth = 1; // Don't expect subdirs, so don't even try
|
||||||
File[] files = dir.listFiles();
|
try {
|
||||||
if (files == null) {
|
Files.walkFileTree(dir.toPath(), EnumSet.noneOf(FileVisitOption.class), maxDepth, new SimpleFileVisitor<Path>() {
|
||||||
return 0;
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||||
|
size[0] += attrs.size();
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
for (File file : files) {
|
|
||||||
size += file.length();
|
@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() {
|
public void refresh() {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import static java.nio.file.StandardOpenOption.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -135,9 +136,13 @@ public class RecordingManager {
|
||||||
public List<Recording> getAll() {
|
public List<Recording> getAll() {
|
||||||
recordingsLock.lock();
|
recordingsLock.lock();
|
||||||
try {
|
try {
|
||||||
|
Instant start = Instant.now();
|
||||||
for (Recording recording : recordings) {
|
for (Recording recording : recordings) {
|
||||||
recording.refresh();
|
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);
|
return new ArrayList<>(recordings);
|
||||||
} finally {
|
} finally {
|
||||||
recordingsLock.unlock();
|
recordingsLock.unlock();
|
||||||
|
|
Loading…
Reference in New Issue