Commit ed450006 authored by Matteo Melli's avatar Matteo Melli

Some performance improvement

Using only Files API from Java 7 and reducing disk checks
parent ffa81564
......@@ -18,7 +18,6 @@
*/
package com.ongres.pgio.main.stats;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Streams;
import com.ongres.pgio.main.config.Config;
......@@ -27,10 +26,10 @@ import com.ongres.pgio.main.stats.parser.ProcessIoParser;
import com.ongres.pgio.main.stats.parser.SystemIoParser;
import com.ongres.pgio.main.stats.serializer.StatSerializer;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
......@@ -48,9 +47,6 @@ import java.util.stream.StreamSupport;
public class StatProcessor {
private static final ImmutableList<String> PROC_FILES_TO_READ =
ImmutableList.of("cmdline", "stat", "io");
private final Config config;
private final StatSerializer serializer;
private final PrintStream err;
......@@ -72,14 +68,14 @@ public class StatProcessor {
}
public StatSnapshot getNext(Optional<StatSnapshot> previousStats) throws Exception {
Map<Integer, ProcessInfo> processInfoMap = reduceSubdirectory(Paths.get("/proc"),
stream -> reduceCurrentProcessInfoList(stream, previousStats));
ImmutableMap<Integer, ProcessInfo> processes = reduceSubdirectory(Paths.get("/proc"),
stream -> reduceCurrentProcessInfoList(stream, previousStats), this::isPidDir);
List<ProcessInfo> filteredProcessInfoList = processInfoMap
List<ProcessInfo> filteredProcessInfoList = processes
.values()
.stream()
.filter(info -> config.getPpid()
.map(ppid -> info.getPid() == ppid || info.isChildOf(ppid, processInfoMap))
.map(ppid -> info.getPid() == ppid || info.isChildOf(ppid, processes))
.orElse(true))
.collect(Collectors.toList());
......@@ -127,32 +123,33 @@ public class StatProcessor {
serializer.serialize(otherStat);
}
return new StatSnapshot(stats, systemStat);
return new StatSnapshot(processes, stats, systemStat);
}
private boolean isPidDir(Path path) {
return IntStream.range(0, path.getFileName().toString().length())
.allMatch(i -> path.getFileName().toString().charAt(i) >= '0'
&& path.getFileName().toString().charAt(i) <= '9');
}
private Map<Integer, ProcessInfo> reduceCurrentProcessInfoList(Stream<File> porcsStream,
private ImmutableMap<Integer, ProcessInfo> reduceCurrentProcessInfoList(Stream<Path> porcsStream,
Optional<StatSnapshot> previousStats) {
return porcsStream
.filter(file -> IntStream.range(0, file.getName().length())
.allMatch(i -> file.getName().charAt(i) >= '0' && file.getName().charAt(i) <= '9'))
.filter(file -> file.canRead())
.filter(file -> file.isDirectory())
.filter(file -> reduceSubdirectory(file.toPath(), procStream -> procStream
.filter(entry -> PROC_FILES_TO_READ.contains(entry.getName()))
.filter(entry -> entry.canRead()).count()) == PROC_FILES_TO_READ.size())
.map(file -> file.getName())
.filter(path -> Files.isReadable(path))
.filter(path -> Files.isDirectory(path))
.map(path -> path.getFileName().toString())
.map(name -> Integer.parseInt(name))
.map(pid -> getPreviousOrParseInfo(previousStats, pid))
.filter(optionalInfo -> optionalInfo.isPresent())
.map(optionalInfo -> optionalInfo.get())
.collect(Collectors.toMap(info -> info.getPid(), info -> info));
.collect(ImmutableMap.toImmutableMap(info -> info.getPid(), info -> info));
}
private <T> T reduceSubdirectory(Path path, Function<Stream<File>, T> streamFunction) {
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path)) {
private <T> T reduceSubdirectory(Path path,
Function<Stream<Path>, T> streamFunction, Filter<Path> filter) {
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path, filter)) {
return streamFunction.apply(StreamSupport
.stream(directoryStream.spliterator(), false)
.map(subPath -> subPath.toFile()));
.stream(directoryStream.spliterator(), false));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
......@@ -160,8 +157,8 @@ public class StatProcessor {
private Optional<ProcessInfo> getPreviousOrParseInfo(
Optional<StatSnapshot> previousStats, Integer pid) {
if (previousStats.isPresent() && previousStats.get().getStats().containsKey(pid)) {
return Optional.of(previousStats.get().getStats().get(pid).getInfo());
if (previousStats.isPresent() && previousStats.get().getProcesses().containsKey(pid)) {
return Optional.of(previousStats.get().getProcesses().get(pid));
} else {
return emptyIfException(() -> new ProcessInfoParser(pid).parse(),
() -> "Can not parse process info " + pid + ": ");
......
......@@ -22,15 +22,22 @@ import com.google.common.collect.ImmutableMap;
public class StatSnapshot {
private final ImmutableMap<Integer, ProcessInfo> processes;
private final ImmutableMap<Integer, ProcessStat> stats;
private final SystemStat systemStat;
public StatSnapshot(ImmutableMap<Integer, ProcessStat> stats, SystemStat systemStat) {
public StatSnapshot(ImmutableMap<Integer, ProcessInfo> processes,
ImmutableMap<Integer, ProcessStat> stats, SystemStat systemStat) {
super();
this.processes = processes;
this.stats = stats;
this.systemStat = systemStat;
}
public ImmutableMap<Integer, ProcessInfo> getProcesses() {
return processes;
}
public ImmutableMap<Integer, ProcessStat> getStats() {
return stats;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment