diff --git a/src/main/java/org/cryptomator/common/vaults/VaultStats.java b/src/main/java/org/cryptomator/common/vaults/VaultStats.java index ac0b8df38..43346b763 100644 --- a/src/main/java/org/cryptomator/common/vaults/VaultStats.java +++ b/src/main/java/org/cryptomator/common/vaults/VaultStats.java @@ -41,6 +41,8 @@ public class VaultStats { private final LongProperty totalBytesDecrypted = new SimpleLongProperty(); private final LongProperty filesRead = new SimpleLongProperty(); private final LongProperty filesWritten = new SimpleLongProperty(); + private final LongProperty filesAccessed = new SimpleLongProperty(); + private final LongProperty totalFilesAccessed = new SimpleLongProperty(); private final ObjectProperty lastActivity = new SimpleObjectProperty<>(); @Inject @@ -82,6 +84,8 @@ public class VaultStats { var oldAccessCount = filesRead.get() + filesWritten.get(); filesRead.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesRead).orElse(0L)); filesWritten.set(stats.map(CryptoFileSystemStats::pollAmountOfAccessesWritten).orElse(0L)); + filesAccessed.set(stats.map(CryptoFileSystemStats::pollAmountOfAccesses).orElse(0L)); + totalFilesAccessed.set(stats.map(CryptoFileSystemStats::pollTotalAmountOfAccesses).orElse(0L)); var newAccessCount = filesRead.get() + filesWritten.get(); // check for any I/O activity @@ -188,6 +192,19 @@ public class VaultStats { public long getFilesWritten() {return filesWritten.get();} + public LongProperty filesAccessed() { + return filesAccessed;} + + public long getFilesAccessed() {return filesAccessed.get();} + + public LongProperty totalFilesAccessed(){ + return totalFilesAccessed; + } + + public long getTotalFilesAccessed(){ + return totalFilesAccessed.get(); + } + public ObjectProperty lastActivityProperty() { return lastActivity; } diff --git a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java index 56729f1fe..dd294a457 100644 --- a/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java +++ b/src/main/java/org/cryptomator/ui/stats/VaultStatisticsController.java @@ -9,8 +9,10 @@ import javax.inject.Inject; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; +import javafx.beans.binding.Bindings; import javafx.beans.binding.DoubleBinding; import javafx.beans.binding.LongBinding; +import javafx.beans.property.LongProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -21,6 +23,7 @@ import javafx.scene.chart.XYChart.Series; import javafx.stage.Stage; import javafx.util.Duration; import java.util.Arrays; +import java.util.concurrent.Callable; @VaultStatisticsScoped public class VaultStatisticsController implements FxController { @@ -32,6 +35,7 @@ public class VaultStatisticsController implements FxController { private final VaultStats stats; private final Series readData; private final Series writeData; + private final Series accessData; private final Timeline ioAnimation; private final LongBinding bpsRead; private final LongBinding bpsWritten; @@ -44,15 +48,20 @@ public class VaultStatisticsController implements FxController { private final LongBinding totalBytesDecrypted; private final LongBinding filesRead; private final LongBinding filesWritten; + private final LongBinding filesAccessed; + private final LongBinding totalFilesAccessed; private final LongBinding bpsEncrypted; private final LongBinding bpsDecrypted; public AreaChart readChart; public AreaChart writeChart; + public AreaChart accessChart; public NumberAxis readChartXAxis; public NumberAxis readChartYAxis; public NumberAxis writeChartXAxis; public NumberAxis writeChartYAxis; + public NumberAxis accessChartXAxis; + public NumberAxis accessChartYAxis; @Inject public VaultStatisticsController(VaultStatisticsComponent component, @VaultStatisticsWindow Stage window, @VaultStatisticsWindow Vault vault) { @@ -60,6 +69,7 @@ public class VaultStatisticsController implements FxController { this.stats = vault.getStats(); this.readData = new Series<>(); this.writeData = new Series<>(); + this.accessData = new Series<>(); this.bpsRead = WeakBindings.bindLong(stats.bytesPerSecondReadProperty()); this.bpsWritten = WeakBindings.bindLong(stats.bytesPerSecondWrittenProperty()); this.cacheHitRate = WeakBindings.bindDouble(stats.cacheHitRateProperty()); @@ -71,11 +81,13 @@ public class VaultStatisticsController implements FxController { this.totalBytesEncrypted = WeakBindings.bindLong(stats.totalBytesEncryptedProperty()); this.filesRead = WeakBindings.bindLong(stats.filesRead()); this.filesWritten = WeakBindings.bindLong(stats.filesWritten()); + this.filesAccessed = WeakBindings.bindLong(stats.filesAccessed()); + this.totalFilesAccessed = WeakBindings.bindLong(stats.totalFilesAccessed()); this.bpsEncrypted = WeakBindings.bindLong(stats.bytesPerSecondEncryptedProperty()); this.bpsDecrypted = WeakBindings.bindLong(stats.bytesPerSecondDecryptedProperty()); this.ioAnimation = new Timeline(); //TODO Research better timer - ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData))); + ioAnimation.getKeyFrames().add(new KeyFrame(Duration.seconds(IO_SAMPLING_INTERVAL), new IoSamplingAnimationHandler(readData, writeData, accessData))); ioAnimation.setCycleCount(Animation.INDEFINITE); ioAnimation.play(); @@ -89,6 +101,7 @@ public class VaultStatisticsController implements FxController { public void initialize() { readChart.getData().addAll(readData); writeChart.getData().addAll(writeData); + accessChart.getData().addAll(accessData); } private class IoSamplingAnimationHandler implements EventHandler { @@ -96,16 +109,21 @@ public class VaultStatisticsController implements FxController { private long step = IO_SAMPLING_STEPS; private final Series decryptedBytesRead; private final Series encryptedBytesWrite; + private final Series accessedFiles; private final long[] maxBuf = new long[IO_SAMPLING_STEPS]; + private final long[] maxAccessBuf = new long[IO_SAMPLING_STEPS]; - public IoSamplingAnimationHandler(Series readData, Series writeData) { + + public IoSamplingAnimationHandler(Series readData, Series writeData, Series accessData) { this.decryptedBytesRead = readData; this.encryptedBytesWrite = writeData; + this.accessedFiles = accessData; // initialize data once and change value of data points later: for (int i = 0; i < IO_SAMPLING_STEPS; i++) { decryptedBytesRead.getData().add(new Data<>(i, 0)); encryptedBytesWrite.getData().add(new Data<>(i, 0)); + accessedFiles.getData().add(new Data<>(i, 0)); } } @@ -114,17 +132,22 @@ public class VaultStatisticsController implements FxController { final long currentStep = step++; final long decBytes = stats.bytesPerSecondReadProperty().get(); final long encBytes = stats.bytesPerSecondWrittenProperty().get(); + final long accFiles = stats.filesAccessed().get(); maxBuf[(int) currentStep % IO_SAMPLING_STEPS] = Math.max(decBytes, encBytes); - long allTimeMax = Arrays.stream(maxBuf).max().orElse(0l); + long allTimeMax = Arrays.stream(maxBuf).max().orElse(0L); + maxAccessBuf[(int) currentStep % IO_SAMPLING_STEPS] = accFiles; + long allTimeMaxAccessedFiles = Arrays.stream(maxAccessBuf).max().orElse(0L); // remove oldest value: decryptedBytesRead.getData().remove(0); encryptedBytesWrite.getData().remove(0); + accessedFiles.getData().remove(0); // add latest value: decryptedBytesRead.getData().add(new Data<>(currentStep, decBytes)); encryptedBytesWrite.getData().add(new Data<>(currentStep, encBytes)); + accessedFiles.getData().add(new Data<>(currentStep, accFiles)); // adjust ranges: readChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); @@ -133,6 +156,9 @@ public class VaultStatisticsController implements FxController { writeChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); writeChartXAxis.setUpperBound(currentStep); writeChartYAxis.setUpperBound(allTimeMax); + accessChartXAxis.setLowerBound(currentStep - IO_SAMPLING_STEPS * 1.0); + accessChartXAxis.setUpperBound(currentStep); + accessChartYAxis.setUpperBound(allTimeMaxAccessedFiles); } } @@ -207,4 +233,12 @@ public class VaultStatisticsController implements FxController { public LongBinding filesWrittenProperty() {return filesWritten;} public long getFilesWritten() {return filesWritten.get();} + + public LongBinding filesAccessedProperty() {return filesAccessed;} + + public long getFilesAccessed() {return filesAccessed.get();} + + public LongBinding totalFilesAccessedProperty() {return totalFilesAccessed;} + + public long getTotalFilesAccessed() {return totalFilesAccessed.get();} } diff --git a/src/main/resources/fxml/stats.fxml b/src/main/resources/fxml/stats.fxml index 219c10ceb..c1f8b2aec 100644 --- a/src/main/resources/fxml/stats.fxml +++ b/src/main/resources/fxml/stats.fxml @@ -13,6 +13,7 @@ + - - - - - - - - - - - + + + + + + + + + + @@ -72,4 +72,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 460b56476..df33193a7 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -301,6 +301,11 @@ stats.encr.total.data.mib=Data encrypted: %.1f MiB stats.encr.total.data.gib=Data encrypted: %.1f GiB stats.write.accessCount=Total writes: %d +## Accesses +stats.access.current=Access: %d +stats.access.total=Total accesses: %d + + # Main Window main.closeBtn.tooltip=Close main.minimizeBtn.tooltip=Minimize